Explicitly add python-numpy dependency to install-build-deps.
[chromium-blink-merge.git] / sandbox / win / src / filesystem_interception.cc
blob179cad5e62f2e676322751ef7513148fd86045c2
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "sandbox/win/src/filesystem_interception.h"
7 #include "sandbox/win/src/crosscall_client.h"
8 #include "sandbox/win/src/ipc_tags.h"
9 #include "sandbox/win/src/policy_params.h"
10 #include "sandbox/win/src/policy_target.h"
11 #include "sandbox/win/src/sandbox_factory.h"
12 #include "sandbox/win/src/sandbox_nt_util.h"
13 #include "sandbox/win/src/sharedmem_ipc_client.h"
14 #include "sandbox/win/src/target_services.h"
16 namespace sandbox {
18 NTSTATUS WINAPI TargetNtCreateFile(NtCreateFileFunction orig_CreateFile,
19 PHANDLE file, ACCESS_MASK desired_access,
20 POBJECT_ATTRIBUTES object_attributes,
21 PIO_STATUS_BLOCK io_status,
22 PLARGE_INTEGER allocation_size,
23 ULONG file_attributes, ULONG sharing,
24 ULONG disposition, ULONG options,
25 PVOID ea_buffer, ULONG ea_length) {
26 // Check if the process can open it first.
27 NTSTATUS status = orig_CreateFile(file, desired_access, object_attributes,
28 io_status, allocation_size,
29 file_attributes, sharing, disposition,
30 options, ea_buffer, ea_length);
31 if (STATUS_ACCESS_DENIED != status)
32 return status;
34 // We don't trust that the IPC can work this early.
35 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
36 return status;
38 wchar_t* name = NULL;
39 do {
40 if (!ValidParameter(file, sizeof(HANDLE), WRITE))
41 break;
42 if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
43 break;
45 void* memory = GetGlobalIPCMemory();
46 if (NULL == memory)
47 break;
49 uint32 attributes = 0;
50 NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
51 NULL);
52 if (!NT_SUCCESS(ret) || NULL == name)
53 break;
55 uint32 desired_access_uint32 = desired_access;
56 uint32 options_uint32 = options;
57 uint32 broker = FALSE;
58 CountedParameterSet<OpenFile> params;
59 params[OpenFile::NAME] = ParamPickerMake(name);
60 params[OpenFile::ACCESS] = ParamPickerMake(desired_access_uint32);
61 params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32);
62 params[OpenFile::BROKER] = ParamPickerMake(broker);
64 if (!QueryBroker(IPC_NTCREATEFILE_TAG, params.GetBase()))
65 break;
67 SharedMemIPCClient ipc(memory);
68 CrossCallReturn answer = {0};
69 // The following call must match in the parameters with
70 // FilesystemDispatcher::ProcessNtCreateFile.
71 ResultCode code = CrossCall(ipc, IPC_NTCREATEFILE_TAG, name, attributes,
72 desired_access_uint32, file_attributes, sharing,
73 disposition, options_uint32, &answer);
74 if (SBOX_ALL_OK != code)
75 break;
77 if (!NT_SUCCESS(answer.nt_status))
78 return answer.nt_status;
80 __try {
81 *file = answer.handle;
82 io_status->Status = answer.nt_status;
83 io_status->Information = answer.extended[0].ulong_ptr;
84 status = io_status->Status;
85 } __except(EXCEPTION_EXECUTE_HANDLER) {
86 break;
88 } while (false);
90 if (name)
91 operator delete(name, NT_ALLOC);
93 return status;
96 NTSTATUS WINAPI TargetNtOpenFile(NtOpenFileFunction orig_OpenFile, PHANDLE file,
97 ACCESS_MASK desired_access,
98 POBJECT_ATTRIBUTES object_attributes,
99 PIO_STATUS_BLOCK io_status, ULONG sharing,
100 ULONG options) {
101 // Check if the process can open it first.
102 NTSTATUS status = orig_OpenFile(file, desired_access, object_attributes,
103 io_status, sharing, options);
104 if (STATUS_ACCESS_DENIED != status)
105 return status;
107 // We don't trust that the IPC can work this early.
108 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
109 return status;
111 wchar_t* name = NULL;
112 do {
113 if (!ValidParameter(file, sizeof(HANDLE), WRITE))
114 break;
115 if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
116 break;
118 void* memory = GetGlobalIPCMemory();
119 if (NULL == memory)
120 break;
122 uint32 attributes;
123 NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
124 NULL);
125 if (!NT_SUCCESS(ret) || NULL == name)
126 break;
128 uint32 desired_access_uint32 = desired_access;
129 uint32 options_uint32 = options;
130 uint32 broker = FALSE;
131 CountedParameterSet<OpenFile> params;
132 params[OpenFile::NAME] = ParamPickerMake(name);
133 params[OpenFile::ACCESS] = ParamPickerMake(desired_access_uint32);
134 params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32);
135 params[OpenFile::BROKER] = ParamPickerMake(broker);
137 if (!QueryBroker(IPC_NTOPENFILE_TAG, params.GetBase()))
138 break;
140 SharedMemIPCClient ipc(memory);
141 CrossCallReturn answer = {0};
142 ResultCode code = CrossCall(ipc, IPC_NTOPENFILE_TAG, name, attributes,
143 desired_access_uint32, sharing, options_uint32,
144 &answer);
145 if (SBOX_ALL_OK != code)
146 break;
148 if (!NT_SUCCESS(answer.nt_status))
149 return answer.nt_status;
151 __try {
152 *file = answer.handle;
153 io_status->Status = answer.nt_status;
154 io_status->Information = answer.extended[0].ulong_ptr;
155 status = io_status->Status;
156 } __except(EXCEPTION_EXECUTE_HANDLER) {
157 break;
159 } while (false);
161 if (name)
162 operator delete(name, NT_ALLOC);
164 return status;
167 NTSTATUS WINAPI TargetNtQueryAttributesFile(
168 NtQueryAttributesFileFunction orig_QueryAttributes,
169 POBJECT_ATTRIBUTES object_attributes,
170 PFILE_BASIC_INFORMATION file_attributes) {
171 // Check if the process can query it first.
172 NTSTATUS status = orig_QueryAttributes(object_attributes, file_attributes);
173 if (STATUS_ACCESS_DENIED != status)
174 return status;
176 // We don't trust that the IPC can work this early.
177 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
178 return status;
180 wchar_t* name = NULL;
181 do {
182 if (!ValidParameter(file_attributes, sizeof(FILE_BASIC_INFORMATION), WRITE))
183 break;
185 void* memory = GetGlobalIPCMemory();
186 if (NULL == memory)
187 break;
189 uint32 attributes = 0;
190 NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
191 NULL);
192 if (!NT_SUCCESS(ret) || NULL == name)
193 break;
195 InOutCountedBuffer file_info(file_attributes,
196 sizeof(FILE_BASIC_INFORMATION));
198 uint32 broker = FALSE;
199 CountedParameterSet<FileName> params;
200 params[FileName::NAME] = ParamPickerMake(name);
201 params[FileName::BROKER] = ParamPickerMake(broker);
203 if (!QueryBroker(IPC_NTQUERYATTRIBUTESFILE_TAG, params.GetBase()))
204 break;
206 SharedMemIPCClient ipc(memory);
207 CrossCallReturn answer = {0};
208 ResultCode code = CrossCall(ipc, IPC_NTQUERYATTRIBUTESFILE_TAG, name,
209 attributes, file_info, &answer);
211 operator delete(name, NT_ALLOC);
213 if (SBOX_ALL_OK != code)
214 break;
216 return answer.nt_status;
218 } while (false);
220 if (name)
221 operator delete(name, NT_ALLOC);
223 return status;
226 NTSTATUS WINAPI TargetNtQueryFullAttributesFile(
227 NtQueryFullAttributesFileFunction orig_QueryFullAttributes,
228 POBJECT_ATTRIBUTES object_attributes,
229 PFILE_NETWORK_OPEN_INFORMATION file_attributes) {
230 // Check if the process can query it first.
231 NTSTATUS status = orig_QueryFullAttributes(object_attributes,
232 file_attributes);
233 if (STATUS_ACCESS_DENIED != status)
234 return status;
236 // We don't trust that the IPC can work this early.
237 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
238 return status;
240 wchar_t* name = NULL;
241 do {
242 if (!ValidParameter(file_attributes, sizeof(FILE_NETWORK_OPEN_INFORMATION),
243 WRITE))
244 break;
246 void* memory = GetGlobalIPCMemory();
247 if (NULL == memory)
248 break;
250 uint32 attributes = 0;
251 NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
252 NULL);
253 if (!NT_SUCCESS(ret) || NULL == name)
254 break;
256 InOutCountedBuffer file_info(file_attributes,
257 sizeof(FILE_NETWORK_OPEN_INFORMATION));
259 uint32 broker = FALSE;
260 CountedParameterSet<FileName> params;
261 params[FileName::NAME] = ParamPickerMake(name);
262 params[FileName::BROKER] = ParamPickerMake(broker);
264 if (!QueryBroker(IPC_NTQUERYFULLATTRIBUTESFILE_TAG, params.GetBase()))
265 break;
267 SharedMemIPCClient ipc(memory);
268 CrossCallReturn answer = {0};
269 ResultCode code = CrossCall(ipc, IPC_NTQUERYFULLATTRIBUTESFILE_TAG, name,
270 attributes, file_info, &answer);
272 operator delete(name, NT_ALLOC);
274 if (SBOX_ALL_OK != code)
275 break;
277 return answer.nt_status;
278 } while (false);
280 if (name)
281 operator delete(name, NT_ALLOC);
283 return status;
286 NTSTATUS WINAPI TargetNtSetInformationFile(
287 NtSetInformationFileFunction orig_SetInformationFile, HANDLE file,
288 PIO_STATUS_BLOCK io_status, PVOID file_info, ULONG length,
289 FILE_INFORMATION_CLASS file_info_class) {
290 // Check if the process can open it first.
291 NTSTATUS status = orig_SetInformationFile(file, io_status, file_info, length,
292 file_info_class);
293 if (STATUS_ACCESS_DENIED != status)
294 return status;
296 // We don't trust that the IPC can work this early.
297 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
298 return status;
300 wchar_t* name = NULL;
301 do {
302 void* memory = GetGlobalIPCMemory();
303 if (NULL == memory)
304 break;
306 if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
307 break;
309 if (!ValidParameter(file_info, length, READ))
310 break;
312 FILE_RENAME_INFORMATION* file_rename_info =
313 reinterpret_cast<FILE_RENAME_INFORMATION*>(file_info);
314 OBJECT_ATTRIBUTES object_attributes;
315 UNICODE_STRING object_name;
316 InitializeObjectAttributes(&object_attributes, &object_name, 0, NULL, NULL);
318 __try {
319 if (!IsSupportedRenameCall(file_rename_info, length, file_info_class))
320 break;
322 object_attributes.RootDirectory = file_rename_info->RootDirectory;
323 object_name.Buffer = file_rename_info->FileName;
324 object_name.Length = object_name.MaximumLength =
325 static_cast<USHORT>(file_rename_info->FileNameLength);
326 } __except(EXCEPTION_EXECUTE_HANDLER) {
327 break;
330 NTSTATUS ret = AllocAndCopyName(&object_attributes, &name, NULL, NULL);
331 if (!NT_SUCCESS(ret) || !name)
332 break;
334 uint32 broker = FALSE;
335 CountedParameterSet<FileName> params;
336 params[FileName::NAME] = ParamPickerMake(name);
337 params[FileName::BROKER] = ParamPickerMake(broker);
339 if (!QueryBroker(IPC_NTSETINFO_RENAME_TAG, params.GetBase()))
340 break;
342 InOutCountedBuffer io_status_buffer(io_status, sizeof(IO_STATUS_BLOCK));
343 // This is actually not an InOut buffer, only In, but using InOut facility
344 // really helps to simplify the code.
345 InOutCountedBuffer file_info_buffer(file_info, length);
347 SharedMemIPCClient ipc(memory);
348 CrossCallReturn answer = {0};
349 ResultCode code = CrossCall(ipc, IPC_NTSETINFO_RENAME_TAG, file,
350 io_status_buffer, file_info_buffer, length,
351 file_info_class, &answer);
353 if (SBOX_ALL_OK != code)
354 break;
356 status = answer.nt_status;
357 } while (false);
359 if (name)
360 operator delete(name, NT_ALLOC);
362 return status;
365 } // namespace sandbox