Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / sandbox / win / src / filesystem_interception.cc
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.
4
5 #include "sandbox/win/src/filesystem_interception.h"
6
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"
15
16 namespace sandbox {
17
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;
33
34   // We don't trust that the IPC can work this early.
35   if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
36     return status;
37
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;
44
45     void* memory = GetGlobalIPCMemory();
46     if (NULL == memory)
47       break;
48
49     uint32 attributes = 0;
50     NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
51                                     NULL);
52     if (!NT_SUCCESS(ret) || NULL == name)
53       break;
54
55     ULONG broker = FALSE;
56     CountedParameterSet<OpenFile> params;
57     params[OpenFile::NAME] = ParamPickerMake(name);
58     params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
59     params[OpenFile::OPTIONS] = ParamPickerMake(options);
60     params[OpenFile::BROKER] = ParamPickerMake(broker);
61
62     if (!QueryBroker(IPC_NTCREATEFILE_TAG, params.GetBase()))
63       break;
64
65     SharedMemIPCClient ipc(memory);
66     CrossCallReturn answer = {0};
67     // The following call must match in the parameters with
68     // FilesystemDispatcher::ProcessNtCreateFile.
69     ResultCode code = CrossCall(ipc, IPC_NTCREATEFILE_TAG, name, attributes,
70                                 desired_access, file_attributes, sharing,
71                                 disposition, options, &answer);
72     if (SBOX_ALL_OK != code)
73       break;
74
75     if (!NT_SUCCESS(answer.nt_status))
76         return answer.nt_status;
77
78     __try {
79       *file = answer.handle;
80       io_status->Status = answer.nt_status;
81       io_status->Information = answer.extended[0].ulong_ptr;
82       status = io_status->Status;
83     } __except(EXCEPTION_EXECUTE_HANDLER) {
84       break;
85     }
86   } while (false);
87
88   if (name)
89     operator delete(name, NT_ALLOC);
90
91   return status;
92 }
93
94 NTSTATUS WINAPI TargetNtOpenFile(NtOpenFileFunction orig_OpenFile, PHANDLE file,
95                                  ACCESS_MASK desired_access,
96                                  POBJECT_ATTRIBUTES object_attributes,
97                                  PIO_STATUS_BLOCK io_status, ULONG sharing,
98                                  ULONG options) {
99   // Check if the process can open it first.
100   NTSTATUS status = orig_OpenFile(file, desired_access, object_attributes,
101                                   io_status, sharing, options);
102   if (STATUS_ACCESS_DENIED != status)
103     return status;
104
105   // We don't trust that the IPC can work this early.
106   if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
107     return status;
108
109   wchar_t* name = NULL;
110   do {
111     if (!ValidParameter(file, sizeof(HANDLE), WRITE))
112       break;
113     if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
114       break;
115
116     void* memory = GetGlobalIPCMemory();
117     if (NULL == memory)
118       break;
119
120     uint32 attributes;
121     NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
122                                     NULL);
123     if (!NT_SUCCESS(ret) || NULL == name)
124       break;
125
126     ULONG broker = FALSE;
127     CountedParameterSet<OpenFile> params;
128     params[OpenFile::NAME] = ParamPickerMake(name);
129     params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
130     params[OpenFile::OPTIONS] = ParamPickerMake(options);
131     params[OpenFile::BROKER] = ParamPickerMake(broker);
132
133     if (!QueryBroker(IPC_NTOPENFILE_TAG, params.GetBase()))
134       break;
135
136     SharedMemIPCClient ipc(memory);
137     CrossCallReturn answer = {0};
138     ResultCode code = CrossCall(ipc, IPC_NTOPENFILE_TAG, name, attributes,
139                                 desired_access, sharing, options, &answer);
140     if (SBOX_ALL_OK != code)
141       break;
142
143     if (!NT_SUCCESS(answer.nt_status))
144       return answer.nt_status;
145
146     __try {
147       *file = answer.handle;
148       io_status->Status = answer.nt_status;
149       io_status->Information = answer.extended[0].ulong_ptr;
150       status = io_status->Status;
151     } __except(EXCEPTION_EXECUTE_HANDLER) {
152       break;
153     }
154   } while (false);
155
156   if (name)
157     operator delete(name, NT_ALLOC);
158
159   return status;
160 }
161
162 NTSTATUS WINAPI TargetNtQueryAttributesFile(
163     NtQueryAttributesFileFunction orig_QueryAttributes,
164     POBJECT_ATTRIBUTES object_attributes,
165     PFILE_BASIC_INFORMATION file_attributes) {
166   // Check if the process can query it first.
167   NTSTATUS status = orig_QueryAttributes(object_attributes, file_attributes);
168   if (STATUS_ACCESS_DENIED != status)
169     return status;
170
171   // We don't trust that the IPC can work this early.
172   if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
173     return status;
174
175   wchar_t* name = NULL;
176   do {
177     if (!ValidParameter(file_attributes, sizeof(FILE_BASIC_INFORMATION), WRITE))
178       break;
179
180     void* memory = GetGlobalIPCMemory();
181     if (NULL == memory)
182       break;
183
184     uint32 attributes = 0;
185     NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
186                                     NULL);
187     if (!NT_SUCCESS(ret) || NULL == name)
188       break;
189
190     InOutCountedBuffer file_info(file_attributes,
191                                  sizeof(FILE_BASIC_INFORMATION));
192
193     ULONG broker = FALSE;
194     CountedParameterSet<FileName> params;
195     params[FileName::NAME] = ParamPickerMake(name);
196     params[FileName::BROKER] = ParamPickerMake(broker);
197
198     if (!QueryBroker(IPC_NTQUERYATTRIBUTESFILE_TAG, params.GetBase()))
199       break;
200
201     SharedMemIPCClient ipc(memory);
202     CrossCallReturn answer = {0};
203     ResultCode code = CrossCall(ipc, IPC_NTQUERYATTRIBUTESFILE_TAG, name,
204                                 attributes, file_info, &answer);
205
206     operator delete(name, NT_ALLOC);
207
208     if (SBOX_ALL_OK != code)
209       break;
210
211     return answer.nt_status;
212
213   } while (false);
214
215   if (name)
216     operator delete(name, NT_ALLOC);
217
218   return status;
219 }
220
221 NTSTATUS WINAPI TargetNtQueryFullAttributesFile(
222     NtQueryFullAttributesFileFunction orig_QueryFullAttributes,
223     POBJECT_ATTRIBUTES object_attributes,
224     PFILE_NETWORK_OPEN_INFORMATION file_attributes) {
225   // Check if the process can query it first.
226   NTSTATUS status = orig_QueryFullAttributes(object_attributes,
227                                              file_attributes);
228   if (STATUS_ACCESS_DENIED != status)
229     return status;
230
231   // We don't trust that the IPC can work this early.
232   if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
233     return status;
234
235   wchar_t* name = NULL;
236   do {
237     if (!ValidParameter(file_attributes, sizeof(FILE_NETWORK_OPEN_INFORMATION),
238                         WRITE))
239       break;
240
241     void* memory = GetGlobalIPCMemory();
242     if (NULL == memory)
243       break;
244
245     uint32 attributes = 0;
246     NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes,
247                                     NULL);
248     if (!NT_SUCCESS(ret) || NULL == name)
249       break;
250
251     InOutCountedBuffer file_info(file_attributes,
252                                  sizeof(FILE_NETWORK_OPEN_INFORMATION));
253
254     ULONG broker = FALSE;
255     CountedParameterSet<FileName> params;
256     params[FileName::NAME] = ParamPickerMake(name);
257     params[FileName::BROKER] = ParamPickerMake(broker);
258
259     if (!QueryBroker(IPC_NTQUERYFULLATTRIBUTESFILE_TAG, params.GetBase()))
260       break;
261
262     SharedMemIPCClient ipc(memory);
263     CrossCallReturn answer = {0};
264     ResultCode code = CrossCall(ipc, IPC_NTQUERYFULLATTRIBUTESFILE_TAG, name,
265                                 attributes, file_info, &answer);
266
267     operator delete(name, NT_ALLOC);
268
269     if (SBOX_ALL_OK != code)
270       break;
271
272     return answer.nt_status;
273   } while (false);
274
275   if (name)
276     operator delete(name, NT_ALLOC);
277
278   return status;
279 }
280
281 NTSTATUS WINAPI TargetNtSetInformationFile(
282     NtSetInformationFileFunction orig_SetInformationFile, HANDLE file,
283     PIO_STATUS_BLOCK io_status, PVOID file_info, ULONG length,
284     FILE_INFORMATION_CLASS file_info_class) {
285   // Check if the process can open it first.
286   NTSTATUS status = orig_SetInformationFile(file, io_status, file_info, length,
287                                             file_info_class);
288   if (STATUS_ACCESS_DENIED != status)
289     return status;
290
291   // We don't trust that the IPC can work this early.
292   if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
293     return status;
294
295   wchar_t* name = NULL;
296   do {
297     void* memory = GetGlobalIPCMemory();
298     if (NULL == memory)
299       break;
300
301     if (!ValidParameter(io_status, sizeof(IO_STATUS_BLOCK), WRITE))
302       break;
303
304     if (!ValidParameter(file_info, length, READ))
305       break;
306
307     FILE_RENAME_INFORMATION* file_rename_info =
308         reinterpret_cast<FILE_RENAME_INFORMATION*>(file_info);
309     OBJECT_ATTRIBUTES object_attributes;
310     UNICODE_STRING object_name;
311     InitializeObjectAttributes(&object_attributes, &object_name, 0, NULL, NULL);
312
313     __try {
314       if (!IsSupportedRenameCall(file_rename_info, length, file_info_class))
315         break;
316
317       object_attributes.RootDirectory = file_rename_info->RootDirectory;
318       object_name.Buffer = file_rename_info->FileName;
319       object_name.Length = object_name.MaximumLength =
320           static_cast<USHORT>(file_rename_info->FileNameLength);
321     } __except(EXCEPTION_EXECUTE_HANDLER) {
322       break;
323     }
324
325     NTSTATUS ret = AllocAndCopyName(&object_attributes, &name, NULL, NULL);
326     if (!NT_SUCCESS(ret) || !name)
327       break;
328
329     ULONG broker = FALSE;
330     CountedParameterSet<FileName> params;
331     params[FileName::NAME] = ParamPickerMake(name);
332     params[FileName::BROKER] = ParamPickerMake(broker);
333
334     if (!QueryBroker(IPC_NTSETINFO_RENAME_TAG, params.GetBase()))
335       break;
336
337     InOutCountedBuffer io_status_buffer(io_status, sizeof(IO_STATUS_BLOCK));
338     // This is actually not an InOut buffer, only In, but using InOut facility
339     // really helps to simplify the code.
340     InOutCountedBuffer file_info_buffer(file_info, length);
341
342     SharedMemIPCClient ipc(memory);
343     CrossCallReturn answer = {0};
344     ResultCode code = CrossCall(ipc, IPC_NTSETINFO_RENAME_TAG, file,
345                                 io_status_buffer, file_info_buffer, length,
346                                 file_info_class, &answer);
347
348     if (SBOX_ALL_OK != code)
349       break;
350
351     status = answer.nt_status;
352   } while (false);
353
354   if (name)
355     operator delete(name, NT_ALLOC);
356
357   return status;
358 }
359
360 }  // namespace sandbox