Roll src/third_party/WebKit e0eac24:489c548 (svn 193311:193320)
[chromium-blink-merge.git] / sandbox / win / src / filesystem_dispatcher.cc
blob4561be4202843b69c0c974d6090e30c62700bc44
1 // Copyright (c) 2006-2010 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_dispatcher.h"
7 #include "sandbox/win/src/crosscall_client.h"
8 #include "sandbox/win/src/filesystem_interception.h"
9 #include "sandbox/win/src/filesystem_policy.h"
10 #include "sandbox/win/src/interception.h"
11 #include "sandbox/win/src/interceptors.h"
12 #include "sandbox/win/src/ipc_tags.h"
13 #include "sandbox/win/src/policy_broker.h"
14 #include "sandbox/win/src/policy_params.h"
15 #include "sandbox/win/src/sandbox.h"
16 #include "sandbox/win/src/sandbox_nt_util.h"
18 namespace sandbox {
20 FilesystemDispatcher::FilesystemDispatcher(PolicyBase* policy_base)
21 : policy_base_(policy_base) {
22 static const IPCCall create_params = {
23 {IPC_NTCREATEFILE_TAG, WCHAR_TYPE, UINT32_TYPE, UINT32_TYPE, UINT32_TYPE,
24 UINT32_TYPE, UINT32_TYPE, UINT32_TYPE},
25 reinterpret_cast<CallbackGeneric>(&FilesystemDispatcher::NtCreateFile)
28 static const IPCCall open_file = {
29 {IPC_NTOPENFILE_TAG, WCHAR_TYPE, UINT32_TYPE, UINT32_TYPE, UINT32_TYPE,
30 UINT32_TYPE},
31 reinterpret_cast<CallbackGeneric>(&FilesystemDispatcher::NtOpenFile)
34 static const IPCCall attribs = {
35 {IPC_NTQUERYATTRIBUTESFILE_TAG, WCHAR_TYPE, UINT32_TYPE, INOUTPTR_TYPE},
36 reinterpret_cast<CallbackGeneric>(
37 &FilesystemDispatcher::NtQueryAttributesFile)
40 static const IPCCall full_attribs = {
41 {IPC_NTQUERYFULLATTRIBUTESFILE_TAG, WCHAR_TYPE, UINT32_TYPE, INOUTPTR_TYPE},
42 reinterpret_cast<CallbackGeneric>(
43 &FilesystemDispatcher::NtQueryFullAttributesFile)
46 static const IPCCall set_info = {
47 {IPC_NTSETINFO_RENAME_TAG, VOIDPTR_TYPE, INOUTPTR_TYPE, INOUTPTR_TYPE,
48 UINT32_TYPE, UINT32_TYPE},
49 reinterpret_cast<CallbackGeneric>(
50 &FilesystemDispatcher::NtSetInformationFile)
53 ipc_calls_.push_back(create_params);
54 ipc_calls_.push_back(open_file);
55 ipc_calls_.push_back(attribs);
56 ipc_calls_.push_back(full_attribs);
57 ipc_calls_.push_back(set_info);
60 bool FilesystemDispatcher::SetupService(InterceptionManager* manager,
61 int service) {
62 switch (service) {
63 case IPC_NTCREATEFILE_TAG:
64 return INTERCEPT_NT(manager, NtCreateFile, CREATE_FILE_ID, 48);
66 case IPC_NTOPENFILE_TAG:
67 return INTERCEPT_NT(manager, NtOpenFile, OPEN_FILE_ID, 28);
69 case IPC_NTQUERYATTRIBUTESFILE_TAG:
70 return INTERCEPT_NT(manager, NtQueryAttributesFile, QUERY_ATTRIB_FILE_ID,
71 12);
73 case IPC_NTQUERYFULLATTRIBUTESFILE_TAG:
74 return INTERCEPT_NT(manager, NtQueryFullAttributesFile,
75 QUERY_FULL_ATTRIB_FILE_ID, 12);
77 case IPC_NTSETINFO_RENAME_TAG:
78 return INTERCEPT_NT(manager, NtSetInformationFile, SET_INFO_FILE_ID, 24);
80 default:
81 return false;
85 bool FilesystemDispatcher::NtCreateFile(IPCInfo* ipc,
86 base::string16* name,
87 uint32 attributes,
88 uint32 desired_access,
89 uint32 file_attributes,
90 uint32 share_access,
91 uint32 create_disposition,
92 uint32 create_options) {
93 if (!PreProcessName(*name, name)) {
94 // The path requested might contain a reparse point.
95 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
96 return true;
99 const wchar_t* filename = name->c_str();
101 uint32 broker = TRUE;
102 CountedParameterSet<OpenFile> params;
103 params[OpenFile::NAME] = ParamPickerMake(filename);
104 params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
105 params[OpenFile::DISPOSITION] = ParamPickerMake(create_disposition);
106 params[OpenFile::OPTIONS] = ParamPickerMake(create_options);
107 params[OpenFile::BROKER] = ParamPickerMake(broker);
109 // To evaluate the policy we need to call back to the policy object. We
110 // are just middlemen in the operation since is the FileSystemPolicy which
111 // knows what to do.
112 EvalResult result = policy_base_->EvalPolicy(IPC_NTCREATEFILE_TAG,
113 params.GetBase());
114 HANDLE handle;
115 ULONG_PTR io_information = 0;
116 NTSTATUS nt_status;
117 if (!FileSystemPolicy::CreateFileAction(result, *ipc->client_info, *name,
118 attributes, desired_access,
119 file_attributes, share_access,
120 create_disposition, create_options,
121 &handle, &nt_status,
122 &io_information)) {
123 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
124 return true;
126 // Return operation status on the IPC.
127 ipc->return_info.extended[0].ulong_ptr = io_information;
128 ipc->return_info.nt_status = nt_status;
129 ipc->return_info.handle = handle;
130 return true;
133 bool FilesystemDispatcher::NtOpenFile(IPCInfo* ipc,
134 base::string16* name,
135 uint32 attributes,
136 uint32 desired_access,
137 uint32 share_access,
138 uint32 open_options) {
139 if (!PreProcessName(*name, name)) {
140 // The path requested might contain a reparse point.
141 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
142 return true;
145 const wchar_t* filename = name->c_str();
147 uint32 broker = TRUE;
148 uint32 create_disposition = FILE_OPEN;
149 CountedParameterSet<OpenFile> params;
150 params[OpenFile::NAME] = ParamPickerMake(filename);
151 params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
152 params[OpenFile::DISPOSITION] = ParamPickerMake(create_disposition);
153 params[OpenFile::OPTIONS] = ParamPickerMake(open_options);
154 params[OpenFile::BROKER] = ParamPickerMake(broker);
156 // To evaluate the policy we need to call back to the policy object. We
157 // are just middlemen in the operation since is the FileSystemPolicy which
158 // knows what to do.
159 EvalResult result = policy_base_->EvalPolicy(IPC_NTOPENFILE_TAG,
160 params.GetBase());
161 HANDLE handle;
162 ULONG_PTR io_information = 0;
163 NTSTATUS nt_status;
164 if (!FileSystemPolicy::OpenFileAction(result, *ipc->client_info, *name,
165 attributes, desired_access,
166 share_access, open_options, &handle,
167 &nt_status, &io_information)) {
168 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
169 return true;
171 // Return operation status on the IPC.
172 ipc->return_info.extended[0].ulong_ptr = io_information;
173 ipc->return_info.nt_status = nt_status;
174 ipc->return_info.handle = handle;
175 return true;
178 bool FilesystemDispatcher::NtQueryAttributesFile(IPCInfo* ipc,
179 base::string16* name,
180 uint32 attributes,
181 CountedBuffer* info) {
182 if (sizeof(FILE_BASIC_INFORMATION) != info->Size())
183 return false;
185 if (!PreProcessName(*name, name)) {
186 // The path requested might contain a reparse point.
187 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
188 return true;
191 uint32 broker = TRUE;
192 const wchar_t* filename = name->c_str();
193 CountedParameterSet<FileName> params;
194 params[FileName::NAME] = ParamPickerMake(filename);
195 params[FileName::BROKER] = ParamPickerMake(broker);
197 // To evaluate the policy we need to call back to the policy object. We
198 // are just middlemen in the operation since is the FileSystemPolicy which
199 // knows what to do.
200 EvalResult result = policy_base_->EvalPolicy(IPC_NTQUERYATTRIBUTESFILE_TAG,
201 params.GetBase());
203 FILE_BASIC_INFORMATION* information =
204 reinterpret_cast<FILE_BASIC_INFORMATION*>(info->Buffer());
205 NTSTATUS nt_status;
206 if (!FileSystemPolicy::QueryAttributesFileAction(result, *ipc->client_info,
207 *name, attributes,
208 information, &nt_status)) {
209 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
210 return true;
213 // Return operation status on the IPC.
214 ipc->return_info.nt_status = nt_status;
215 return true;
218 bool FilesystemDispatcher::NtQueryFullAttributesFile(IPCInfo* ipc,
219 base::string16* name,
220 uint32 attributes,
221 CountedBuffer* info) {
222 if (sizeof(FILE_NETWORK_OPEN_INFORMATION) != info->Size())
223 return false;
225 if (!PreProcessName(*name, name)) {
226 // The path requested might contain a reparse point.
227 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
228 return true;
231 uint32 broker = TRUE;
232 const wchar_t* filename = name->c_str();
233 CountedParameterSet<FileName> params;
234 params[FileName::NAME] = ParamPickerMake(filename);
235 params[FileName::BROKER] = ParamPickerMake(broker);
237 // To evaluate the policy we need to call back to the policy object. We
238 // are just middlemen in the operation since is the FileSystemPolicy which
239 // knows what to do.
240 EvalResult result = policy_base_->EvalPolicy(
241 IPC_NTQUERYFULLATTRIBUTESFILE_TAG, params.GetBase());
243 FILE_NETWORK_OPEN_INFORMATION* information =
244 reinterpret_cast<FILE_NETWORK_OPEN_INFORMATION*>(info->Buffer());
245 NTSTATUS nt_status;
246 if (!FileSystemPolicy::QueryFullAttributesFileAction(result,
247 *ipc->client_info,
248 *name, attributes,
249 information,
250 &nt_status)) {
251 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
252 return true;
255 // Return operation status on the IPC.
256 ipc->return_info.nt_status = nt_status;
257 return true;
260 bool FilesystemDispatcher::NtSetInformationFile(IPCInfo* ipc,
261 HANDLE handle,
262 CountedBuffer* status,
263 CountedBuffer* info,
264 uint32 length,
265 uint32 info_class) {
266 if (sizeof(IO_STATUS_BLOCK) != status->Size())
267 return false;
268 if (length != info->Size())
269 return false;
271 FILE_RENAME_INFORMATION* rename_info =
272 reinterpret_cast<FILE_RENAME_INFORMATION*>(info->Buffer());
274 if (!IsSupportedRenameCall(rename_info, length, info_class))
275 return false;
277 base::string16 name;
278 name.assign(rename_info->FileName, rename_info->FileNameLength /
279 sizeof(rename_info->FileName[0]));
280 if (!PreProcessName(name, &name)) {
281 // The path requested might contain a reparse point.
282 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
283 return true;
286 uint32 broker = TRUE;
287 const wchar_t* filename = name.c_str();
288 CountedParameterSet<FileName> params;
289 params[FileName::NAME] = ParamPickerMake(filename);
290 params[FileName::BROKER] = ParamPickerMake(broker);
292 // To evaluate the policy we need to call back to the policy object. We
293 // are just middlemen in the operation since is the FileSystemPolicy which
294 // knows what to do.
295 EvalResult result = policy_base_->EvalPolicy(IPC_NTSETINFO_RENAME_TAG,
296 params.GetBase());
298 IO_STATUS_BLOCK* io_status =
299 reinterpret_cast<IO_STATUS_BLOCK*>(status->Buffer());
300 NTSTATUS nt_status;
301 if (!FileSystemPolicy::SetInformationFileAction(result, *ipc->client_info,
302 handle, rename_info, length,
303 info_class, io_status,
304 &nt_status)) {
305 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
306 return true;
309 // Return operation status on the IPC.
310 ipc->return_info.nt_status = nt_status;
311 return true;
314 } // namespace sandbox