Don't preload rarely seen large images
[chromium-blink-merge.git] / sandbox / win / src / filesystem_interception.cc
blob459f7ace2d66612442b069c036cab51b2f10ec75
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 disposition_uint32 = disposition;
58 uint32 broker = FALSE;
59 CountedParameterSet<OpenFile> params;
60 params[OpenFile::NAME] = ParamPickerMake(name);
61 params[OpenFile::ACCESS] = ParamPickerMake(desired_access_uint32);
62 params[OpenFile::DISPOSITION] = ParamPickerMake(disposition_uint32);
63 params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32);
64 params[OpenFile::BROKER] = ParamPickerMake(broker);
66 if (!QueryBroker(IPC_NTCREATEFILE_TAG, params.GetBase()))
67 break;
69 SharedMemIPCClient ipc(memory);
70 CrossCallReturn answer = {0};
71 // The following call must match in the parameters with
72 // FilesystemDispatcher::ProcessNtCreateFile.
73 ResultCode code = CrossCall(ipc, IPC_NTCREATEFILE_TAG, name, attributes,
74 desired_access_uint32, file_attributes, sharing,
75 disposition, options_uint32, &answer);
76 if (SBOX_ALL_OK != code)
77 break;
79 status = answer.nt_status;
81 if (!NT_SUCCESS(answer.nt_status))
82 break;
84 __try {
85 *file = answer.handle;
86 io_status->Status = answer.nt_status;
87 io_status->Information = answer.extended[0].ulong_ptr;
88 } __except(EXCEPTION_EXECUTE_HANDLER) {
89 break;
91 } while (false);
93 if (name)
94 operator delete(name, NT_ALLOC);
96 return status;
99 NTSTATUS WINAPI TargetNtOpenFile(NtOpenFileFunction orig_OpenFile, PHANDLE file,
100 ACCESS_MASK desired_access,
101 POBJECT_ATTRIBUTES object_attributes,
102 PIO_STATUS_BLOCK io_status, ULONG sharing,
103 ULONG options) {
104 // Check if the process can open it first.
105 NTSTATUS status = orig_OpenFile(file, desired_access, object_attributes,
106 io_status, sharing, options);
107 if (STATUS_ACCESS_DENIED != status)
108 return status;
110 // We don't trust that the IPC can work this early.
111 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
112 return status;
114 wchar_t* name = NULL;
115 do {
116 if (!ValidParameter(file, sizeof(HANDLE), WRITE))
117 break;
118 if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
119 break;
121 void* memory = GetGlobalIPCMemory();
122 if (NULL == memory)
123 break;
125 uint32 attributes;
126 NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
127 NULL);
128 if (!NT_SUCCESS(ret) || NULL == name)
129 break;
131 uint32 desired_access_uint32 = desired_access;
132 uint32 options_uint32 = options;
133 uint32 disposition_uint32 = FILE_OPEN;
134 uint32 broker = FALSE;
135 CountedParameterSet<OpenFile> params;
136 params[OpenFile::NAME] = ParamPickerMake(name);
137 params[OpenFile::ACCESS] = ParamPickerMake(desired_access_uint32);
138 params[OpenFile::DISPOSITION] = ParamPickerMake(disposition_uint32);
139 params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32);
140 params[OpenFile::BROKER] = ParamPickerMake(broker);
142 if (!QueryBroker(IPC_NTOPENFILE_TAG, params.GetBase()))
143 break;
145 SharedMemIPCClient ipc(memory);
146 CrossCallReturn answer = {0};
147 ResultCode code = CrossCall(ipc, IPC_NTOPENFILE_TAG, name, attributes,
148 desired_access_uint32, sharing, options_uint32,
149 &answer);
150 if (SBOX_ALL_OK != code)
151 break;
153 status = answer.nt_status;
155 if (!NT_SUCCESS(answer.nt_status))
156 break;
158 __try {
159 *file = answer.handle;
160 io_status->Status = answer.nt_status;
161 io_status->Information = answer.extended[0].ulong_ptr;
162 } __except(EXCEPTION_EXECUTE_HANDLER) {
163 break;
165 } while (false);
167 if (name)
168 operator delete(name, NT_ALLOC);
170 return status;
173 NTSTATUS WINAPI TargetNtQueryAttributesFile(
174 NtQueryAttributesFileFunction orig_QueryAttributes,
175 POBJECT_ATTRIBUTES object_attributes,
176 PFILE_BASIC_INFORMATION file_attributes) {
177 // Check if the process can query it first.
178 NTSTATUS status = orig_QueryAttributes(object_attributes, file_attributes);
179 if (STATUS_ACCESS_DENIED != status)
180 return status;
182 // We don't trust that the IPC can work this early.
183 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
184 return status;
186 wchar_t* name = NULL;
187 do {
188 if (!ValidParameter(file_attributes, sizeof(FILE_BASIC_INFORMATION), WRITE))
189 break;
191 void* memory = GetGlobalIPCMemory();
192 if (NULL == memory)
193 break;
195 uint32 attributes = 0;
196 NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
197 NULL);
198 if (!NT_SUCCESS(ret) || NULL == name)
199 break;
201 InOutCountedBuffer file_info(file_attributes,
202 sizeof(FILE_BASIC_INFORMATION));
204 uint32 broker = FALSE;
205 CountedParameterSet<FileName> params;
206 params[FileName::NAME] = ParamPickerMake(name);
207 params[FileName::BROKER] = ParamPickerMake(broker);
209 if (!QueryBroker(IPC_NTQUERYATTRIBUTESFILE_TAG, params.GetBase()))
210 break;
212 SharedMemIPCClient ipc(memory);
213 CrossCallReturn answer = {0};
214 ResultCode code = CrossCall(ipc, IPC_NTQUERYATTRIBUTESFILE_TAG, name,
215 attributes, file_info, &answer);
217 if (SBOX_ALL_OK != code)
218 break;
220 status = answer.nt_status;
222 } while (false);
224 if (name)
225 operator delete(name, NT_ALLOC);
227 return status;
230 NTSTATUS WINAPI TargetNtQueryFullAttributesFile(
231 NtQueryFullAttributesFileFunction orig_QueryFullAttributes,
232 POBJECT_ATTRIBUTES object_attributes,
233 PFILE_NETWORK_OPEN_INFORMATION file_attributes) {
234 // Check if the process can query it first.
235 NTSTATUS status = orig_QueryFullAttributes(object_attributes,
236 file_attributes);
237 if (STATUS_ACCESS_DENIED != status)
238 return status;
240 // We don't trust that the IPC can work this early.
241 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
242 return status;
244 wchar_t* name = NULL;
245 do {
246 if (!ValidParameter(file_attributes, sizeof(FILE_NETWORK_OPEN_INFORMATION),
247 WRITE))
248 break;
250 void* memory = GetGlobalIPCMemory();
251 if (NULL == memory)
252 break;
254 uint32 attributes = 0;
255 NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
256 NULL);
257 if (!NT_SUCCESS(ret) || NULL == name)
258 break;
260 InOutCountedBuffer file_info(file_attributes,
261 sizeof(FILE_NETWORK_OPEN_INFORMATION));
263 uint32 broker = FALSE;
264 CountedParameterSet<FileName> params;
265 params[FileName::NAME] = ParamPickerMake(name);
266 params[FileName::BROKER] = ParamPickerMake(broker);
268 if (!QueryBroker(IPC_NTQUERYFULLATTRIBUTESFILE_TAG, params.GetBase()))
269 break;
271 SharedMemIPCClient ipc(memory);
272 CrossCallReturn answer = {0};
273 ResultCode code = CrossCall(ipc, IPC_NTQUERYFULLATTRIBUTESFILE_TAG, name,
274 attributes, file_info, &answer);
276 if (SBOX_ALL_OK != code)
277 break;
279 status = answer.nt_status;
280 } while (false);
282 if (name)
283 operator delete(name, NT_ALLOC);
285 return status;
288 NTSTATUS WINAPI TargetNtSetInformationFile(
289 NtSetInformationFileFunction orig_SetInformationFile, HANDLE file,
290 PIO_STATUS_BLOCK io_status, PVOID file_info, ULONG length,
291 FILE_INFORMATION_CLASS file_info_class) {
292 // Check if the process can open it first.
293 NTSTATUS status = orig_SetInformationFile(file, io_status, file_info, length,
294 file_info_class);
295 if (STATUS_ACCESS_DENIED != status)
296 return status;
298 // We don't trust that the IPC can work this early.
299 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
300 return status;
302 wchar_t* name = NULL;
303 do {
304 void* memory = GetGlobalIPCMemory();
305 if (NULL == memory)
306 break;
308 if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
309 break;
311 if (!ValidParameter(file_info, length, READ))
312 break;
314 FILE_RENAME_INFORMATION* file_rename_info =
315 reinterpret_cast<FILE_RENAME_INFORMATION*>(file_info);
316 OBJECT_ATTRIBUTES object_attributes;
317 UNICODE_STRING object_name;
318 InitializeObjectAttributes(&object_attributes, &object_name, 0, NULL, NULL);
320 __try {
321 if (!IsSupportedRenameCall(file_rename_info, length, file_info_class))
322 break;
324 object_attributes.RootDirectory = file_rename_info->RootDirectory;
325 object_name.Buffer = file_rename_info->FileName;
326 object_name.Length = object_name.MaximumLength =
327 static_cast<USHORT>(file_rename_info->FileNameLength);
328 } __except(EXCEPTION_EXECUTE_HANDLER) {
329 break;
332 NTSTATUS ret = AllocAndCopyName(&object_attributes, &name, NULL, NULL);
333 if (!NT_SUCCESS(ret) || !name)
334 break;
336 uint32 broker = FALSE;
337 CountedParameterSet<FileName> params;
338 params[FileName::NAME] = ParamPickerMake(name);
339 params[FileName::BROKER] = ParamPickerMake(broker);
341 if (!QueryBroker(IPC_NTSETINFO_RENAME_TAG, params.GetBase()))
342 break;
344 InOutCountedBuffer io_status_buffer(io_status, sizeof(IO_STATUS_BLOCK));
345 // This is actually not an InOut buffer, only In, but using InOut facility
346 // really helps to simplify the code.
347 InOutCountedBuffer file_info_buffer(file_info, length);
349 SharedMemIPCClient ipc(memory);
350 CrossCallReturn answer = {0};
351 ResultCode code = CrossCall(ipc, IPC_NTSETINFO_RENAME_TAG, file,
352 io_status_buffer, file_info_buffer, length,
353 file_info_class, &answer);
355 if (SBOX_ALL_OK != code)
356 break;
358 status = answer.nt_status;
359 } while (false);
361 if (name)
362 operator delete(name, NT_ALLOC);
364 return status;
367 } // namespace sandbox