// Copyright (c) 2006-2008 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/sync_interception.h" #include "sandbox/win/src/crosscall_client.h" #include "sandbox/win/src/ipc_tags.h" #include "sandbox/win/src/policy_params.h" #include "sandbox/win/src/policy_target.h" #include "sandbox/win/src/sandbox_factory.h" #include "sandbox/win/src/sandbox_nt_util.h" #include "sandbox/win/src/sharedmem_ipc_client.h" #include "sandbox/win/src/target_services.h" namespace sandbox { ResultCode ProxyCreateEvent(LPCWSTR name, uint32 initial_state, EVENT_TYPE event_type, void* ipc_memory, CrossCallReturn* answer) { CountedParameterSet params; params[NameBased::NAME] = ParamPickerMake(name); if (!QueryBroker(IPC_CREATEEVENT_TAG, params.GetBase())) return SBOX_ERROR_GENERIC; SharedMemIPCClient ipc(ipc_memory); ResultCode code = CrossCall(ipc, IPC_CREATEEVENT_TAG, name, event_type, initial_state, answer); return code; } ResultCode ProxyOpenEvent(LPCWSTR name, uint32 desired_access, void* ipc_memory, CrossCallReturn* answer) { CountedParameterSet params; params[OpenEventParams::NAME] = ParamPickerMake(name); params[OpenEventParams::ACCESS] = ParamPickerMake(desired_access); if (!QueryBroker(IPC_OPENEVENT_TAG, params.GetBase())) return SBOX_ERROR_GENERIC; SharedMemIPCClient ipc(ipc_memory); ResultCode code = CrossCall(ipc, IPC_OPENEVENT_TAG, name, desired_access, answer); return code; } NTSTATUS WINAPI TargetNtCreateEvent(NtCreateEventFunction orig_CreateEvent, PHANDLE event_handle, ACCESS_MASK desired_access, POBJECT_ATTRIBUTES object_attributes, EVENT_TYPE event_type, BOOLEAN initial_state) { NTSTATUS status = orig_CreateEvent(event_handle, desired_access, object_attributes, event_type, initial_state); if (status != STATUS_ACCESS_DENIED || !object_attributes) return status; // We don't trust that the IPC can work this early. if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) return status; do { if (!ValidParameter(event_handle, sizeof(HANDLE), WRITE)) break; void* memory = GetGlobalIPCMemory(); if (memory == NULL) break; OBJECT_ATTRIBUTES object_attribs_copy = *object_attributes; // The RootDirectory points to BaseNamedObjects. We can ignore it. object_attribs_copy.RootDirectory = NULL; wchar_t* name = NULL; uint32 attributes = 0; NTSTATUS ret = AllocAndCopyName(&object_attribs_copy, &name, &attributes, NULL); if (!NT_SUCCESS(ret) || name == NULL) break; CrossCallReturn answer = {0}; answer.nt_status = status; ResultCode code = ProxyCreateEvent(name, initial_state, event_type, memory, &answer); operator delete(name, NT_ALLOC); if (code != SBOX_ALL_OK) { status = answer.nt_status; break; } __try { *event_handle = answer.handle; status = STATUS_SUCCESS; } __except(EXCEPTION_EXECUTE_HANDLER) { break; } } while (false); return status; } NTSTATUS WINAPI TargetNtOpenEvent(NtOpenEventFunction orig_OpenEvent, PHANDLE event_handle, ACCESS_MASK desired_access, POBJECT_ATTRIBUTES object_attributes) { NTSTATUS status = orig_OpenEvent(event_handle, desired_access, object_attributes); if (status != STATUS_ACCESS_DENIED || !object_attributes) return status; // We don't trust that the IPC can work this early. if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) return status; do { if (!ValidParameter(event_handle, sizeof(HANDLE), WRITE)) break; void* memory = GetGlobalIPCMemory(); if (memory == NULL) break; OBJECT_ATTRIBUTES object_attribs_copy = *object_attributes; // The RootDirectory points to BaseNamedObjects. We can ignore it. object_attribs_copy.RootDirectory = NULL; wchar_t* name = NULL; uint32 attributes = 0; NTSTATUS ret = AllocAndCopyName(&object_attribs_copy, &name, &attributes, NULL); if (!NT_SUCCESS(ret) || name == NULL) break; CrossCallReturn answer = {0}; answer.nt_status = status; ResultCode code = ProxyOpenEvent(name, desired_access, memory, &answer); operator delete(name, NT_ALLOC); if (code != SBOX_ALL_OK) { status = answer.nt_status; break; } __try { *event_handle = answer.handle; status = STATUS_SUCCESS; } __except(EXCEPTION_EXECUTE_HANDLER) { break; } } while (false); return status; } } // namespace sandbox