123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "sandbox/win/src/filesystem_dispatcher.h"
- #include <stdint.h>
- #include "sandbox/win/src/crosscall_client.h"
- #include "sandbox/win/src/filesystem_interception.h"
- #include "sandbox/win/src/filesystem_policy.h"
- #include "sandbox/win/src/interception.h"
- #include "sandbox/win/src/interceptors.h"
- #include "sandbox/win/src/ipc_tags.h"
- #include "sandbox/win/src/policy_broker.h"
- #include "sandbox/win/src/policy_params.h"
- #include "sandbox/win/src/sandbox.h"
- #include "sandbox/win/src/sandbox_nt_util.h"
- namespace sandbox {
- FilesystemDispatcher::FilesystemDispatcher(PolicyBase* policy_base)
- : policy_base_(policy_base) {
- static const IPCCall create_params = {
- {IpcTag::NTCREATEFILE,
- {WCHAR_TYPE, UINT32_TYPE, UINT32_TYPE, UINT32_TYPE, UINT32_TYPE,
- UINT32_TYPE, UINT32_TYPE}},
- reinterpret_cast<CallbackGeneric>(&FilesystemDispatcher::NtCreateFile)};
- static const IPCCall open_file = {
- {IpcTag::NTOPENFILE,
- {WCHAR_TYPE, UINT32_TYPE, UINT32_TYPE, UINT32_TYPE, UINT32_TYPE}},
- reinterpret_cast<CallbackGeneric>(&FilesystemDispatcher::NtOpenFile)};
- static const IPCCall attribs = {
- {IpcTag::NTQUERYATTRIBUTESFILE, {WCHAR_TYPE, UINT32_TYPE, INOUTPTR_TYPE}},
- reinterpret_cast<CallbackGeneric>(
- &FilesystemDispatcher::NtQueryAttributesFile)};
- static const IPCCall full_attribs = {
- {IpcTag::NTQUERYFULLATTRIBUTESFILE,
- {WCHAR_TYPE, UINT32_TYPE, INOUTPTR_TYPE}},
- reinterpret_cast<CallbackGeneric>(
- &FilesystemDispatcher::NtQueryFullAttributesFile)};
- static const IPCCall set_info = {
- {IpcTag::NTSETINFO_RENAME,
- {VOIDPTR_TYPE, INOUTPTR_TYPE, INOUTPTR_TYPE, UINT32_TYPE, UINT32_TYPE}},
- reinterpret_cast<CallbackGeneric>(
- &FilesystemDispatcher::NtSetInformationFile)};
- ipc_calls_.push_back(create_params);
- ipc_calls_.push_back(open_file);
- ipc_calls_.push_back(attribs);
- ipc_calls_.push_back(full_attribs);
- ipc_calls_.push_back(set_info);
- }
- bool FilesystemDispatcher::SetupService(InterceptionManager* manager,
- IpcTag service) {
- switch (service) {
- case IpcTag::NTCREATEFILE:
- return INTERCEPT_NT(manager, NtCreateFile, CREATE_FILE_ID, 48);
- case IpcTag::NTOPENFILE:
- return INTERCEPT_NT(manager, NtOpenFile, OPEN_FILE_ID, 28);
- case IpcTag::NTQUERYATTRIBUTESFILE:
- return INTERCEPT_NT(manager, NtQueryAttributesFile, QUERY_ATTRIB_FILE_ID,
- 12);
- case IpcTag::NTQUERYFULLATTRIBUTESFILE:
- return INTERCEPT_NT(manager, NtQueryFullAttributesFile,
- QUERY_FULL_ATTRIB_FILE_ID, 12);
- case IpcTag::NTSETINFO_RENAME:
- return INTERCEPT_NT(manager, NtSetInformationFile, SET_INFO_FILE_ID, 24);
- default:
- return false;
- }
- }
- bool FilesystemDispatcher::NtCreateFile(IPCInfo* ipc,
- std::wstring* name,
- uint32_t attributes,
- uint32_t desired_access,
- uint32_t file_attributes,
- uint32_t share_access,
- uint32_t create_disposition,
- uint32_t create_options) {
- if (!PreProcessName(name)) {
- // The path requested might contain a reparse point.
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
- EvalResult result = EvalPolicy(IpcTag::NTCREATEFILE, *name, desired_access,
- create_disposition == FILE_OPEN);
- HANDLE handle;
- ULONG_PTR io_information = 0;
- NTSTATUS nt_status;
- if (!FileSystemPolicy::CreateFileAction(
- result, *ipc->client_info, *name, attributes, desired_access,
- file_attributes, share_access, create_disposition, create_options,
- &handle, &nt_status, &io_information)) {
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
- // Return operation status on the IPC.
- ipc->return_info.extended[0].ulong_ptr = io_information;
- ipc->return_info.nt_status = nt_status;
- ipc->return_info.handle = handle;
- return true;
- }
- bool FilesystemDispatcher::NtOpenFile(IPCInfo* ipc,
- std::wstring* name,
- uint32_t attributes,
- uint32_t desired_access,
- uint32_t share_access,
- uint32_t open_options) {
- if (!PreProcessName(name)) {
- // The path requested might contain a reparse point.
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
- EvalResult result =
- EvalPolicy(IpcTag::NTOPENFILE, *name, desired_access, true);
- HANDLE handle;
- ULONG_PTR io_information = 0;
- NTSTATUS nt_status;
- if (!FileSystemPolicy::OpenFileAction(
- result, *ipc->client_info, *name, attributes, desired_access,
- share_access, open_options, &handle, &nt_status, &io_information)) {
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
- // Return operation status on the IPC.
- ipc->return_info.extended[0].ulong_ptr = io_information;
- ipc->return_info.nt_status = nt_status;
- ipc->return_info.handle = handle;
- return true;
- }
- bool FilesystemDispatcher::NtQueryAttributesFile(IPCInfo* ipc,
- std::wstring* name,
- uint32_t attributes,
- CountedBuffer* info) {
- if (sizeof(FILE_BASIC_INFORMATION) != info->Size())
- return false;
- if (!PreProcessName(name)) {
- // The path requested might contain a reparse point.
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
- EvalResult result = EvalPolicy(IpcTag::NTQUERYATTRIBUTESFILE, *name);
- FILE_BASIC_INFORMATION* information =
- reinterpret_cast<FILE_BASIC_INFORMATION*>(info->Buffer());
- NTSTATUS nt_status;
- if (!FileSystemPolicy::QueryAttributesFileAction(result, *ipc->client_info,
- *name, attributes,
- information, &nt_status)) {
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
- // Return operation status on the IPC.
- ipc->return_info.nt_status = nt_status;
- return true;
- }
- bool FilesystemDispatcher::NtQueryFullAttributesFile(IPCInfo* ipc,
- std::wstring* name,
- uint32_t attributes,
- CountedBuffer* info) {
- if (sizeof(FILE_NETWORK_OPEN_INFORMATION) != info->Size())
- return false;
- if (!PreProcessName(name)) {
- // The path requested might contain a reparse point.
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
- EvalResult result = EvalPolicy(IpcTag::NTQUERYFULLATTRIBUTESFILE, *name);
- FILE_NETWORK_OPEN_INFORMATION* information =
- reinterpret_cast<FILE_NETWORK_OPEN_INFORMATION*>(info->Buffer());
- NTSTATUS nt_status;
- if (!FileSystemPolicy::QueryFullAttributesFileAction(
- result, *ipc->client_info, *name, attributes, information,
- &nt_status)) {
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
- // Return operation status on the IPC.
- ipc->return_info.nt_status = nt_status;
- return true;
- }
- bool FilesystemDispatcher::NtSetInformationFile(IPCInfo* ipc,
- HANDLE handle,
- CountedBuffer* status,
- CountedBuffer* info,
- uint32_t length,
- uint32_t info_class) {
- if (sizeof(IO_STATUS_BLOCK) != status->Size())
- return false;
- if (length != info->Size())
- return false;
- FILE_RENAME_INFORMATION* rename_info =
- reinterpret_cast<FILE_RENAME_INFORMATION*>(info->Buffer());
- if (!IsSupportedRenameCall(rename_info, length, info_class))
- return false;
- std::wstring name;
- name.assign(rename_info->FileName,
- rename_info->FileNameLength / sizeof(rename_info->FileName[0]));
- if (!PreProcessName(&name)) {
- // The path requested might contain a reparse point.
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
- EvalResult result = EvalPolicy(IpcTag::NTSETINFO_RENAME, name);
- IO_STATUS_BLOCK* io_status =
- reinterpret_cast<IO_STATUS_BLOCK*>(status->Buffer());
- NTSTATUS nt_status;
- if (!FileSystemPolicy::SetInformationFileAction(
- result, *ipc->client_info, handle, rename_info, length, info_class,
- io_status, &nt_status)) {
- ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
- return true;
- }
- // Return operation status on the IPC.
- ipc->return_info.nt_status = nt_status;
- return true;
- }
- EvalResult FilesystemDispatcher::EvalPolicy(IpcTag ipc_tag,
- const std::wstring& name,
- uint32_t desired_access,
- bool open_only) {
- CountedParameterSet<OpenFile> params;
- const wchar_t* name_ptr = name.c_str();
- params[OpenFile::NAME] = ParamPickerMake(name_ptr);
- params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
- uint32_t open_only_int = open_only;
- params[OpenFile::OPENONLY] = ParamPickerMake(open_only_int);
- return policy_base_->EvalPolicy(ipc_tag, params.GetBase());
- }
- } // namespace sandbox
|