Update OWNERS file for src/tools/auto-bisect.
[chromium-blink-merge.git] / sandbox / win / src / filesystem_dispatcher.cc
blob354fe4f1dc6a7c64b19b84a2865b29acc1736289
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::OPTIONS] = ParamPickerMake(create_options);
106 params[OpenFile::BROKER] = ParamPickerMake(broker);
108 // To evaluate the policy we need to call back to the policy object. We
109 // are just middlemen in the operation since is the FileSystemPolicy which
110 // knows what to do.
111 EvalResult result = policy_base_->EvalPolicy(IPC_NTCREATEFILE_TAG,
112 params.GetBase());
113 HANDLE handle;
114 ULONG_PTR io_information = 0;
115 NTSTATUS nt_status;
116 if (!FileSystemPolicy::CreateFileAction(result, *ipc->client_info, *name,
117 attributes, desired_access,
118 file_attributes, share_access,
119 create_disposition, create_options,
120 &handle, &nt_status,
121 &io_information)) {
122 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
123 return true;
125 // Return operation status on the IPC.
126 ipc->return_info.extended[0].ulong_ptr = io_information;
127 ipc->return_info.nt_status = nt_status;
128 ipc->return_info.handle = handle;
129 return true;
132 bool FilesystemDispatcher::NtOpenFile(IPCInfo* ipc,
133 base::string16* name,
134 uint32 attributes,
135 uint32 desired_access,
136 uint32 share_access,
137 uint32 open_options) {
138 if (!PreProcessName(*name, name)) {
139 // The path requested might contain a reparse point.
140 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
141 return true;
144 const wchar_t* filename = name->c_str();
146 uint32 broker = TRUE;
147 CountedParameterSet<OpenFile> params;
148 params[OpenFile::NAME] = ParamPickerMake(filename);
149 params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
150 params[OpenFile::OPTIONS] = ParamPickerMake(open_options);
151 params[OpenFile::BROKER] = ParamPickerMake(broker);
153 // To evaluate the policy we need to call back to the policy object. We
154 // are just middlemen in the operation since is the FileSystemPolicy which
155 // knows what to do.
156 EvalResult result = policy_base_->EvalPolicy(IPC_NTOPENFILE_TAG,
157 params.GetBase());
158 HANDLE handle;
159 ULONG_PTR io_information = 0;
160 NTSTATUS nt_status;
161 if (!FileSystemPolicy::OpenFileAction(result, *ipc->client_info, *name,
162 attributes, desired_access,
163 share_access, open_options, &handle,
164 &nt_status, &io_information)) {
165 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
166 return true;
168 // Return operation status on the IPC.
169 ipc->return_info.extended[0].ulong_ptr = io_information;
170 ipc->return_info.nt_status = nt_status;
171 ipc->return_info.handle = handle;
172 return true;
175 bool FilesystemDispatcher::NtQueryAttributesFile(IPCInfo* ipc,
176 base::string16* name,
177 uint32 attributes,
178 CountedBuffer* info) {
179 if (sizeof(FILE_BASIC_INFORMATION) != info->Size())
180 return false;
182 if (!PreProcessName(*name, name)) {
183 // The path requested might contain a reparse point.
184 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
185 return true;
188 uint32 broker = TRUE;
189 const wchar_t* filename = name->c_str();
190 CountedParameterSet<FileName> params;
191 params[FileName::NAME] = ParamPickerMake(filename);
192 params[FileName::BROKER] = ParamPickerMake(broker);
194 // To evaluate the policy we need to call back to the policy object. We
195 // are just middlemen in the operation since is the FileSystemPolicy which
196 // knows what to do.
197 EvalResult result = policy_base_->EvalPolicy(IPC_NTQUERYATTRIBUTESFILE_TAG,
198 params.GetBase());
200 FILE_BASIC_INFORMATION* information =
201 reinterpret_cast<FILE_BASIC_INFORMATION*>(info->Buffer());
202 NTSTATUS nt_status;
203 if (!FileSystemPolicy::QueryAttributesFileAction(result, *ipc->client_info,
204 *name, attributes,
205 information, &nt_status)) {
206 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
207 return true;
210 // Return operation status on the IPC.
211 ipc->return_info.nt_status = nt_status;
212 return true;
215 bool FilesystemDispatcher::NtQueryFullAttributesFile(IPCInfo* ipc,
216 base::string16* name,
217 uint32 attributes,
218 CountedBuffer* info) {
219 if (sizeof(FILE_NETWORK_OPEN_INFORMATION) != info->Size())
220 return false;
222 if (!PreProcessName(*name, name)) {
223 // The path requested might contain a reparse point.
224 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
225 return true;
228 uint32 broker = TRUE;
229 const wchar_t* filename = name->c_str();
230 CountedParameterSet<FileName> params;
231 params[FileName::NAME] = ParamPickerMake(filename);
232 params[FileName::BROKER] = ParamPickerMake(broker);
234 // To evaluate the policy we need to call back to the policy object. We
235 // are just middlemen in the operation since is the FileSystemPolicy which
236 // knows what to do.
237 EvalResult result = policy_base_->EvalPolicy(
238 IPC_NTQUERYFULLATTRIBUTESFILE_TAG, params.GetBase());
240 FILE_NETWORK_OPEN_INFORMATION* information =
241 reinterpret_cast<FILE_NETWORK_OPEN_INFORMATION*>(info->Buffer());
242 NTSTATUS nt_status;
243 if (!FileSystemPolicy::QueryFullAttributesFileAction(result,
244 *ipc->client_info,
245 *name, attributes,
246 information,
247 &nt_status)) {
248 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
249 return true;
252 // Return operation status on the IPC.
253 ipc->return_info.nt_status = nt_status;
254 return true;
257 bool FilesystemDispatcher::NtSetInformationFile(IPCInfo* ipc,
258 HANDLE handle,
259 CountedBuffer* status,
260 CountedBuffer* info,
261 uint32 length,
262 uint32 info_class) {
263 if (sizeof(IO_STATUS_BLOCK) != status->Size())
264 return false;
265 if (length != info->Size())
266 return false;
268 FILE_RENAME_INFORMATION* rename_info =
269 reinterpret_cast<FILE_RENAME_INFORMATION*>(info->Buffer());
271 if (!IsSupportedRenameCall(rename_info, length, info_class))
272 return false;
274 base::string16 name;
275 name.assign(rename_info->FileName, rename_info->FileNameLength /
276 sizeof(rename_info->FileName[0]));
277 if (!PreProcessName(name, &name)) {
278 // The path requested might contain a reparse point.
279 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
280 return true;
283 uint32 broker = TRUE;
284 const wchar_t* filename = name.c_str();
285 CountedParameterSet<FileName> params;
286 params[FileName::NAME] = ParamPickerMake(filename);
287 params[FileName::BROKER] = ParamPickerMake(broker);
289 // To evaluate the policy we need to call back to the policy object. We
290 // are just middlemen in the operation since is the FileSystemPolicy which
291 // knows what to do.
292 EvalResult result = policy_base_->EvalPolicy(IPC_NTSETINFO_RENAME_TAG,
293 params.GetBase());
295 IO_STATUS_BLOCK* io_status =
296 reinterpret_cast<IO_STATUS_BLOCK*>(status->Buffer());
297 NTSTATUS nt_status;
298 if (!FileSystemPolicy::SetInformationFileAction(result, *ipc->client_info,
299 handle, rename_info, length,
300 info_class, io_status,
301 &nt_status)) {
302 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
303 return true;
306 // Return operation status on the IPC.
307 ipc->return_info.nt_status = nt_status;
308 return true;
311 } // namespace sandbox