| Index: sandbox/win/src/sync_interception.cc
|
| ===================================================================
|
| --- sandbox/win/src/sync_interception.cc (revision 230780)
|
| +++ sandbox/win/src/sync_interception.cc (working copy)
|
| @@ -17,33 +17,25 @@
|
|
|
| ResultCode ProxyCreateEvent(LPCWSTR name,
|
| BOOL initial_state,
|
| - BOOL manual_reset,
|
| + EVENT_TYPE event_type,
|
| + void* ipc_memory,
|
| CrossCallReturn* answer) {
|
| - void* memory = GetGlobalIPCMemory();
|
| - if (!memory)
|
| - return SBOX_ERROR_GENERIC;
|
| -
|
| CountedParameterSet<NameBased> params;
|
| params[NameBased::NAME] = ParamPickerMake(name);
|
|
|
| if (!QueryBroker(IPC_CREATEEVENT_TAG, params.GetBase()))
|
| return SBOX_ERROR_GENERIC;
|
|
|
| - SharedMemIPCClient ipc(memory);
|
| - ResultCode code = CrossCall(ipc, IPC_CREATEEVENT_TAG, name, manual_reset,
|
| + SharedMemIPCClient ipc(ipc_memory);
|
| + ResultCode code = CrossCall(ipc, IPC_CREATEEVENT_TAG, name, event_type,
|
| initial_state, answer);
|
| return code;
|
| }
|
|
|
| ResultCode ProxyOpenEvent(LPCWSTR name,
|
| ACCESS_MASK desired_access,
|
| - BOOL inherit_handle,
|
| + void* ipc_memory,
|
| CrossCallReturn* answer) {
|
| - void* memory = GetGlobalIPCMemory();
|
| - if (!memory)
|
| - return SBOX_ERROR_GENERIC;
|
| -
|
| - uint32 inherit_handle_ipc = inherit_handle;
|
| CountedParameterSet<OpenEventParams> params;
|
| params[OpenEventParams::NAME] = ParamPickerMake(name);
|
| params[OpenEventParams::ACCESS] = ParamPickerMake(desired_access);
|
| @@ -51,135 +43,119 @@
|
| if (!QueryBroker(IPC_OPENEVENT_TAG, params.GetBase()))
|
| return SBOX_ERROR_GENERIC;
|
|
|
| - SharedMemIPCClient ipc(memory);
|
| + SharedMemIPCClient ipc(ipc_memory);
|
| ResultCode code = CrossCall(ipc, IPC_OPENEVENT_TAG, name, desired_access,
|
| - inherit_handle_ipc, answer);
|
| + answer);
|
|
|
| return code;
|
| }
|
|
|
| -HANDLE WINAPI TargetCreateEventW(CreateEventWFunction orig_CreateEvent,
|
| - LPSECURITY_ATTRIBUTES security_attributes,
|
| - BOOL manual_reset,
|
| - BOOL initial_state,
|
| - LPCWSTR name) {
|
| - // Check if the process can create it first.
|
| - HANDLE handle = orig_CreateEvent(security_attributes, manual_reset,
|
| - initial_state, name);
|
| - if (handle || !name)
|
| - return handle;
|
| +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 NULL;
|
| + return status;
|
|
|
| - DWORD original_error = ::GetLastError();
|
| + do {
|
| + if (!ValidParameter(event_handle, sizeof(HANDLE), WRITE))
|
| + break;
|
|
|
| - CrossCallReturn answer = {0};
|
| - ResultCode code = ProxyCreateEvent(name, initial_state, manual_reset,
|
| - &answer);
|
| + void* memory = GetGlobalIPCMemory();
|
| + if (memory == NULL)
|
| + break;
|
|
|
| - if (code == SBOX_ALL_OK) {
|
| - ::SetLastError(answer.win32_result);
|
| - return answer.handle;
|
| - }
|
| - ::SetLastError(original_error);
|
| - return NULL;
|
| -}
|
| + OBJECT_ATTRIBUTES object_attribs_copy = *object_attributes;
|
| + // The RootDirectory points to BaseNamedObjects. We can ignore it.
|
| + object_attribs_copy.RootDirectory = NULL;
|
|
|
| -HANDLE WINAPI TargetCreateEventA(CreateEventAFunction orig_CreateEvent,
|
| - LPSECURITY_ATTRIBUTES security_attributes,
|
| - BOOL manual_reset,
|
| - BOOL initial_state,
|
| - LPCSTR name) {
|
| - // Check if the process can create it first.
|
| - HANDLE handle = orig_CreateEvent(security_attributes, manual_reset,
|
| - initial_state, name);
|
| - if (handle || !name)
|
| - return handle;
|
| + wchar_t* name = NULL;
|
| + uint32 attributes = 0;
|
| + NTSTATUS ret = AllocAndCopyName(&object_attribs_copy, &name, &attributes,
|
| + NULL);
|
| + if (!NT_SUCCESS(ret) || name == NULL)
|
| + break;
|
|
|
| - // We don't trust that the IPC can work this early.
|
| - if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
|
| - return NULL;
|
| + CrossCallReturn answer = {0};
|
| + answer.nt_status = status;
|
| + ResultCode code = ProxyCreateEvent(name, initial_state, event_type, memory,
|
| + &answer);
|
| + operator delete(name, NT_ALLOC);
|
|
|
| - DWORD original_error = ::GetLastError();
|
| + 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);
|
|
|
| - UNICODE_STRING* wide_name = AnsiToUnicode(name);
|
| - if (!wide_name)
|
| - return NULL;
|
| -
|
| - CrossCallReturn answer = {0};
|
| - ResultCode code = ProxyCreateEvent(wide_name->Buffer, initial_state,
|
| - manual_reset, &answer);
|
| - operator delete(wide_name, NT_ALLOC);
|
| -
|
| - if (code == SBOX_ALL_OK) {
|
| - ::SetLastError(answer.win32_result);
|
| - return answer.handle;
|
| - }
|
| - ::SetLastError(original_error);
|
| - return NULL;
|
| + return status;
|
| }
|
|
|
| -// Interception of OpenEventW on the child process.
|
| -// It should never be called directly
|
| -HANDLE WINAPI TargetOpenEventW(OpenEventWFunction orig_OpenEvent,
|
| - DWORD desired_access,
|
| - BOOL inherit_handle,
|
| - LPCWSTR name) {
|
| - // Check if the process can open it first.
|
| - HANDLE handle = orig_OpenEvent(desired_access, inherit_handle, name);
|
| - if (handle || !name)
|
| - return handle;
|
| +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 NULL;
|
| + return status;
|
|
|
| - DWORD original_error = ::GetLastError();
|
| + do {
|
| + if (!ValidParameter(event_handle, sizeof(HANDLE), WRITE))
|
| + break;
|
|
|
| - CrossCallReturn answer = {0};
|
| + void* memory = GetGlobalIPCMemory();
|
| + if (memory == NULL)
|
| + break;
|
|
|
| - ResultCode code = ProxyOpenEvent(name, desired_access, inherit_handle,
|
| - &answer);
|
| - if (code == SBOX_ALL_OK) {
|
| - ::SetLastError(answer.win32_result);
|
| - return answer.handle;
|
| - }
|
| - ::SetLastError(original_error);
|
| - return NULL;
|
| -}
|
| + OBJECT_ATTRIBUTES object_attribs_copy = *object_attributes;
|
| + // The RootDirectory points to BaseNamedObjects. We can ignore it.
|
| + object_attribs_copy.RootDirectory = NULL;
|
|
|
| -HANDLE WINAPI TargetOpenEventA(OpenEventAFunction orig_OpenEvent,
|
| - DWORD desired_access,
|
| - BOOL inherit_handle,
|
| - LPCSTR name) {
|
| - // Check if the process can open it first.
|
| - HANDLE handle = orig_OpenEvent(desired_access, inherit_handle, name);
|
| - if (handle || !name)
|
| - return handle;
|
| + wchar_t* name = NULL;
|
| + uint32 attributes = 0;
|
| + NTSTATUS ret = AllocAndCopyName(&object_attribs_copy, &name, &attributes,
|
| + NULL);
|
| + if (!NT_SUCCESS(ret) || name == NULL)
|
| + break;
|
|
|
| - // We don't trust that the IPC can work this early.
|
| - if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
|
| - return NULL;
|
| + CrossCallReturn answer = {0};
|
| + answer.nt_status = status;
|
| + ResultCode code = ProxyOpenEvent(name, desired_access, memory, &answer);
|
| + operator delete(name, NT_ALLOC);
|
|
|
| - DWORD original_error = ::GetLastError();
|
| + 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);
|
|
|
| - UNICODE_STRING* wide_name = AnsiToUnicode(name);
|
| - if (!wide_name)
|
| - return NULL;
|
| -
|
| - CrossCallReturn answer = {0};
|
| - ResultCode code = ProxyOpenEvent(wide_name->Buffer, desired_access,
|
| - inherit_handle, &answer);
|
| - operator delete(wide_name, NT_ALLOC);
|
| -
|
| - if (code == SBOX_ALL_OK) {
|
| - ::SetLastError(answer.win32_result);
|
| - return answer.handle;
|
| - }
|
| - ::SetLastError(original_error);
|
| - return NULL;
|
| + return status;
|
| }
|
|
|
| } // namespace sandbox
|
|
|