blob: cbf5cb0af707f8e67ee96ef468abe2056ee2c0a9 [file] [log] [blame]
// 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 <stdint.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_t initial_state,
EVENT_TYPE event_type,
void* ipc_memory,
CrossCallReturn* answer) {
CountedParameterSet<NameBased> 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_t desired_access,
void* ipc_memory,
CrossCallReturn* answer) {
CountedParameterSet<OpenEventParams> 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)
break;
OBJECT_ATTRIBUTES object_attribs_copy = *object_attributes;
// The RootDirectory points to BaseNamedObjects. We can ignore it.
object_attribs_copy.RootDirectory = nullptr;
std::unique_ptr<wchar_t, NtAllocDeleter> name;
uint32_t attributes = 0;
NTSTATUS ret =
AllocAndCopyName(&object_attribs_copy, &name, &attributes, nullptr);
if (!NT_SUCCESS(ret) || !name)
break;
CrossCallReturn answer = {0};
answer.nt_status = status;
ResultCode code = ProxyCreateEvent(name.get(), initial_state, event_type,
memory, &answer);
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)
break;
OBJECT_ATTRIBUTES object_attribs_copy = *object_attributes;
// The RootDirectory points to BaseNamedObjects. We can ignore it.
object_attribs_copy.RootDirectory = nullptr;
std::unique_ptr<wchar_t, NtAllocDeleter> name;
uint32_t attributes = 0;
NTSTATUS ret =
AllocAndCopyName(&object_attribs_copy, &name, &attributes, nullptr);
if (!NT_SUCCESS(ret) || !name)
break;
CrossCallReturn answer = {0};
answer.nt_status = status;
ResultCode code =
ProxyOpenEvent(name.get(), desired_access, memory, &answer);
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