security/sandbox/win/src/filesystem_dispatcher.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.

     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, ULONG_TYPE, ULONG_TYPE, ULONG_TYPE,
    24      ULONG_TYPE, ULONG_TYPE, ULONG_TYPE},
    25     reinterpret_cast<CallbackGeneric>(&FilesystemDispatcher::NtCreateFile)
    26   };
    28   static const IPCCall open_file = {
    29     {IPC_NTOPENFILE_TAG, WCHAR_TYPE, ULONG_TYPE, ULONG_TYPE, ULONG_TYPE,
    30      ULONG_TYPE},
    31     reinterpret_cast<CallbackGeneric>(&FilesystemDispatcher::NtOpenFile)
    32   };
    34   static const IPCCall attribs = {
    35     {IPC_NTQUERYATTRIBUTESFILE_TAG, WCHAR_TYPE, ULONG_TYPE, INOUTPTR_TYPE},
    36     reinterpret_cast<CallbackGeneric>(
    37         &FilesystemDispatcher::NtQueryAttributesFile)
    38   };
    40   static const IPCCall full_attribs = {
    41     {IPC_NTQUERYFULLATTRIBUTESFILE_TAG, WCHAR_TYPE, ULONG_TYPE, INOUTPTR_TYPE},
    42     reinterpret_cast<CallbackGeneric>(
    43           &FilesystemDispatcher::NtQueryFullAttributesFile)
    44   };
    46   static const IPCCall set_info = {
    47     {IPC_NTSETINFO_RENAME_TAG, VOIDPTR_TYPE, INOUTPTR_TYPE, INOUTPTR_TYPE,
    48      ULONG_TYPE, ULONG_TYPE},
    49     reinterpret_cast<CallbackGeneric>(
    50         &FilesystemDispatcher::NtSetInformationFile)
    51   };
    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);
    58 }
    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;
    82   }
    83 }
    85 bool FilesystemDispatcher::NtCreateFile(
    86     IPCInfo* ipc, std::wstring* name, DWORD attributes, DWORD desired_access,
    87     DWORD file_attributes, DWORD share_access, DWORD create_disposition,
    88     DWORD create_options) {
    89   if (!PreProcessName(*name, name)) {
    90     // The path requested might contain a reparse point.
    91     ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
    92     return true;
    93   }
    95   const wchar_t* filename = name->c_str();
    97   ULONG broker = TRUE;
    98   CountedParameterSet<OpenFile> params;
    99   params[OpenFile::NAME] = ParamPickerMake(filename);
   100   params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
   101   params[OpenFile::OPTIONS] = ParamPickerMake(create_options);
   102   params[OpenFile::BROKER] = ParamPickerMake(broker);
   104   // To evaluate the policy we need to call back to the policy object. We
   105   // are just middlemen in the operation since is the FileSystemPolicy which
   106   // knows what to do.
   107   EvalResult result = policy_base_->EvalPolicy(IPC_NTCREATEFILE_TAG,
   108                                                params.GetBase());
   109   HANDLE handle;
   110   ULONG_PTR io_information = 0;
   111   NTSTATUS nt_status;
   112   if (!FileSystemPolicy::CreateFileAction(result, *ipc->client_info, *name,
   113                                           attributes, desired_access,
   114                                           file_attributes, share_access,
   115                                           create_disposition, create_options,
   116                                           &handle, &nt_status,
   117                                           &io_information)) {
   118     ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
   119     return true;
   120   }
   121   // Return operation status on the IPC.
   122   ipc->return_info.extended[0].ulong_ptr = io_information;
   123   ipc->return_info.nt_status = nt_status;
   124   ipc->return_info.handle = handle;
   125   return true;
   126 }
   128 bool FilesystemDispatcher::NtOpenFile(
   129     IPCInfo* ipc, std::wstring* name, DWORD attributes, DWORD desired_access,
   130     DWORD share_access, DWORD open_options) {
   131   if (!PreProcessName(*name, name)) {
   132     // The path requested might contain a reparse point.
   133     ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
   134     return true;
   135   }
   137   const wchar_t* filename = name->c_str();
   139   ULONG broker = TRUE;
   140   CountedParameterSet<OpenFile> params;
   141   params[OpenFile::NAME] = ParamPickerMake(filename);
   142   params[OpenFile::ACCESS] = ParamPickerMake(desired_access);
   143   params[OpenFile::OPTIONS] = ParamPickerMake(open_options);
   144   params[OpenFile::BROKER] = ParamPickerMake(broker);
   146   // To evaluate the policy we need to call back to the policy object. We
   147   // are just middlemen in the operation since is the FileSystemPolicy which
   148   // knows what to do.
   149   EvalResult result = policy_base_->EvalPolicy(IPC_NTOPENFILE_TAG,
   150                                                params.GetBase());
   151   HANDLE handle;
   152   ULONG_PTR io_information = 0;
   153   NTSTATUS nt_status;
   154   if (!FileSystemPolicy::OpenFileAction(result, *ipc->client_info, *name,
   155                                         attributes, desired_access,
   156                                         share_access, open_options, &handle,
   157                                         &nt_status, &io_information)) {
   158     ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
   159     return true;
   160   }
   161   // Return operation status on the IPC.
   162   ipc->return_info.extended[0].ulong_ptr = io_information;
   163   ipc->return_info.nt_status = nt_status;
   164   ipc->return_info.handle = handle;
   165   return true;
   166 }
   168 bool FilesystemDispatcher::NtQueryAttributesFile(
   169     IPCInfo* ipc, std::wstring* name, DWORD attributes, CountedBuffer* info) {
   170   if (sizeof(FILE_BASIC_INFORMATION) != info->Size())
   171     return false;
   173   if (!PreProcessName(*name, name)) {
   174     // The path requested might contain a reparse point.
   175     ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
   176     return true;
   177   }
   179   ULONG broker = TRUE;
   180   const wchar_t* filename = name->c_str();
   181   CountedParameterSet<FileName> params;
   182   params[FileName::NAME] = ParamPickerMake(filename);
   183   params[FileName::BROKER] = ParamPickerMake(broker);
   185   // To evaluate the policy we need to call back to the policy object. We
   186   // are just middlemen in the operation since is the FileSystemPolicy which
   187   // knows what to do.
   188   EvalResult result = policy_base_->EvalPolicy(IPC_NTQUERYATTRIBUTESFILE_TAG,
   189                                                params.GetBase());
   191   FILE_BASIC_INFORMATION* information =
   192         reinterpret_cast<FILE_BASIC_INFORMATION*>(info->Buffer());
   193   NTSTATUS nt_status;
   194   if (!FileSystemPolicy::QueryAttributesFileAction(result, *ipc->client_info,
   195                                                    *name, attributes,
   196                                                    information, &nt_status)) {
   197     ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
   198     return true;
   199   }
   201   // Return operation status on the IPC.
   202   ipc->return_info.nt_status = nt_status;
   203   return true;
   204 }
   206 bool FilesystemDispatcher::NtQueryFullAttributesFile(
   207     IPCInfo* ipc, std::wstring* name, DWORD attributes, CountedBuffer* info) {
   208   if (sizeof(FILE_NETWORK_OPEN_INFORMATION) != info->Size())
   209     return false;
   211   if (!PreProcessName(*name, name)) {
   212     // The path requested might contain a reparse point.
   213     ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
   214     return true;
   215   }
   217   ULONG broker = TRUE;
   218   const wchar_t* filename = name->c_str();
   219   CountedParameterSet<FileName> params;
   220   params[FileName::NAME] = ParamPickerMake(filename);
   221   params[FileName::BROKER] = ParamPickerMake(broker);
   223   // To evaluate the policy we need to call back to the policy object. We
   224   // are just middlemen in the operation since is the FileSystemPolicy which
   225   // knows what to do.
   226   EvalResult result = policy_base_->EvalPolicy(
   227                           IPC_NTQUERYFULLATTRIBUTESFILE_TAG, params.GetBase());
   229   FILE_NETWORK_OPEN_INFORMATION* information =
   230         reinterpret_cast<FILE_NETWORK_OPEN_INFORMATION*>(info->Buffer());
   231   NTSTATUS nt_status;
   232   if (!FileSystemPolicy::QueryFullAttributesFileAction(result,
   233                                                        *ipc->client_info,
   234                                                        *name, attributes,
   235                                                        information,
   236                                                        &nt_status)) {
   237     ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
   238     return true;
   239   }
   241   // Return operation status on the IPC.
   242   ipc->return_info.nt_status = nt_status;
   243   return true;
   244 }
   246 bool FilesystemDispatcher::NtSetInformationFile(
   247     IPCInfo* ipc, HANDLE handle, CountedBuffer* status, CountedBuffer* info,
   248     DWORD length, DWORD info_class) {
   249   if (sizeof(IO_STATUS_BLOCK) != status->Size())
   250     return false;
   251   if (length != info->Size())
   252     return false;
   254   FILE_RENAME_INFORMATION* rename_info =
   255       reinterpret_cast<FILE_RENAME_INFORMATION*>(info->Buffer());
   257   if (!IsSupportedRenameCall(rename_info, length, info_class))
   258     return false;
   260   std::wstring name;
   261   name.assign(rename_info->FileName, rename_info->FileNameLength /
   262                                      sizeof(rename_info->FileName[0]));
   263   if (!PreProcessName(name, &name)) {
   264     // The path requested might contain a reparse point.
   265     ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
   266     return true;
   267   }
   269   ULONG broker = TRUE;
   270   const wchar_t* filename = name.c_str();
   271   CountedParameterSet<FileName> params;
   272   params[FileName::NAME] = ParamPickerMake(filename);
   273   params[FileName::BROKER] = ParamPickerMake(broker);
   275   // To evaluate the policy we need to call back to the policy object. We
   276   // are just middlemen in the operation since is the FileSystemPolicy which
   277   // knows what to do.
   278   EvalResult result = policy_base_->EvalPolicy(IPC_NTSETINFO_RENAME_TAG,
   279                                                params.GetBase());
   281   IO_STATUS_BLOCK* io_status =
   282         reinterpret_cast<IO_STATUS_BLOCK*>(status->Buffer());
   283   NTSTATUS nt_status;
   284   if (!FileSystemPolicy::SetInformationFileAction(result, *ipc->client_info,
   285                                                   handle, rename_info, length,
   286                                                   info_class, io_status,
   287                                                   &nt_status)) {
   288     ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
   289     return true;
   290   }
   292   // Return operation status on the IPC.
   293   ipc->return_info.nt_status = nt_status;
   294   return true;
   295 }
   297 }  // namespace sandbox

mercurial