Home | History | Annotate | Download | only in src
      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.
      4 
      5 #include "sandbox/win/src/sync_interception.h"
      6 
      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"
     15 
     16 namespace sandbox {
     17 
     18 ResultCode ProxyCreateEvent(LPCWSTR name,
     19                             BOOL initial_state,
     20                             EVENT_TYPE event_type,
     21                             void* ipc_memory,
     22                             CrossCallReturn* answer) {
     23   CountedParameterSet<NameBased> params;
     24   params[NameBased::NAME] = ParamPickerMake(name);
     25 
     26   if (!QueryBroker(IPC_CREATEEVENT_TAG, params.GetBase()))
     27     return SBOX_ERROR_GENERIC;
     28 
     29   SharedMemIPCClient ipc(ipc_memory);
     30   ResultCode code = CrossCall(ipc, IPC_CREATEEVENT_TAG, name, event_type,
     31                               initial_state, answer);
     32   return code;
     33 }
     34 
     35 ResultCode ProxyOpenEvent(LPCWSTR name,
     36                           ACCESS_MASK desired_access,
     37                           void* ipc_memory,
     38                           CrossCallReturn* answer) {
     39   CountedParameterSet<OpenEventParams> params;
     40   params[OpenEventParams::NAME] = ParamPickerMake(name);
     41   params[OpenEventParams::ACCESS] = ParamPickerMake(desired_access);
     42 
     43   if (!QueryBroker(IPC_OPENEVENT_TAG, params.GetBase()))
     44     return SBOX_ERROR_GENERIC;
     45 
     46   SharedMemIPCClient ipc(ipc_memory);
     47   ResultCode code = CrossCall(ipc, IPC_OPENEVENT_TAG, name, desired_access,
     48                               answer);
     49 
     50   return code;
     51 }
     52 
     53 NTSTATUS WINAPI TargetNtCreateEvent(NtCreateEventFunction orig_CreateEvent,
     54                                     PHANDLE event_handle,
     55                                     ACCESS_MASK desired_access,
     56                                     POBJECT_ATTRIBUTES object_attributes,
     57                                     EVENT_TYPE event_type,
     58                                     BOOLEAN initial_state) {
     59   NTSTATUS status = orig_CreateEvent(event_handle, desired_access,
     60                                      object_attributes, event_type,
     61                                      initial_state);
     62   if (status != STATUS_ACCESS_DENIED || !object_attributes)
     63     return status;
     64 
     65   // We don't trust that the IPC can work this early.
     66   if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
     67     return status;
     68 
     69   do {
     70     if (!ValidParameter(event_handle, sizeof(HANDLE), WRITE))
     71       break;
     72 
     73     void* memory = GetGlobalIPCMemory();
     74     if (memory == NULL)
     75       break;
     76 
     77     OBJECT_ATTRIBUTES object_attribs_copy = *object_attributes;
     78     // The RootDirectory points to BaseNamedObjects. We can ignore it.
     79     object_attribs_copy.RootDirectory = NULL;
     80 
     81     wchar_t* name = NULL;
     82     uint32 attributes = 0;
     83     NTSTATUS ret = AllocAndCopyName(&object_attribs_copy, &name, &attributes,
     84                                     NULL);
     85     if (!NT_SUCCESS(ret) || name == NULL)
     86       break;
     87 
     88     CrossCallReturn answer = {0};
     89     answer.nt_status = status;
     90     ResultCode code = ProxyCreateEvent(name, initial_state, event_type, memory,
     91                                        &answer);
     92     operator delete(name, NT_ALLOC);
     93 
     94     if (code != SBOX_ALL_OK) {
     95       status = answer.nt_status;
     96       break;
     97     }
     98     __try {
     99       *event_handle = answer.handle;
    100       status = STATUS_SUCCESS;
    101     } __except(EXCEPTION_EXECUTE_HANDLER) {
    102       break;
    103     }
    104   } while (false);
    105 
    106   return status;
    107 }
    108 
    109 NTSTATUS WINAPI TargetNtOpenEvent(NtOpenEventFunction orig_OpenEvent,
    110                                   PHANDLE event_handle,
    111                                   ACCESS_MASK desired_access,
    112                                   POBJECT_ATTRIBUTES object_attributes) {
    113   NTSTATUS status = orig_OpenEvent(event_handle, desired_access,
    114                                    object_attributes);
    115   if (status != STATUS_ACCESS_DENIED || !object_attributes)
    116     return status;
    117 
    118   // We don't trust that the IPC can work this early.
    119   if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
    120     return status;
    121 
    122   do {
    123     if (!ValidParameter(event_handle, sizeof(HANDLE), WRITE))
    124       break;
    125 
    126     void* memory = GetGlobalIPCMemory();
    127     if (memory == NULL)
    128       break;
    129 
    130     OBJECT_ATTRIBUTES object_attribs_copy = *object_attributes;
    131     // The RootDirectory points to BaseNamedObjects. We can ignore it.
    132     object_attribs_copy.RootDirectory = NULL;
    133 
    134     wchar_t* name = NULL;
    135     uint32 attributes = 0;
    136     NTSTATUS ret = AllocAndCopyName(&object_attribs_copy, &name, &attributes,
    137                                     NULL);
    138     if (!NT_SUCCESS(ret) || name == NULL)
    139       break;
    140 
    141     CrossCallReturn answer = {0};
    142     answer.nt_status = status;
    143     ResultCode code = ProxyOpenEvent(name, desired_access, memory, &answer);
    144     operator delete(name, NT_ALLOC);
    145 
    146     if (code != SBOX_ALL_OK) {
    147       status = answer.nt_status;
    148       break;
    149     }
    150     __try {
    151       *event_handle = answer.handle;
    152       status = STATUS_SUCCESS;
    153     } __except(EXCEPTION_EXECUTE_HANDLER) {
    154       break;
    155     }
    156   } while (false);
    157 
    158   return status;
    159 }
    160 
    161 }  // namespace sandbox
    162