security/sandbox/win/src/filesystem_interception.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial