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.

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

mercurial