// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "sandbox/win/src/process_thread_dispatcher.h"
#include <stddef.h>
#include <stdint.h>
#include "base/notreached.h"
#include "sandbox/win/src/crosscall_client.h"
#include "sandbox/win/src/interception.h"
#include "sandbox/win/src/interceptors.h"
#include "sandbox/win/src/ipc_tags.h"
#include "sandbox/win/src/policy_broker.h"
#include "sandbox/win/src/policy_params.h"
#include "sandbox/win/src/process_thread_interception.h"
#include "sandbox/win/src/process_thread_policy.h"
#include "sandbox/win/src/sandbox.h"
namespace sandbox {
ThreadProcessDispatcher::ThreadProcessDispatcher() {
static const IPCCall open_thread = {
{IpcTag::NTOPENTHREAD, {UINT32_TYPE, UINT32_TYPE}},
reinterpret_cast<CallbackGeneric>(
&ThreadProcessDispatcher::NtOpenThread)};
static const IPCCall process_tokenex = {
{IpcTag::NTOPENPROCESSTOKENEX, {VOIDPTR_TYPE, UINT32_TYPE, UINT32_TYPE}},
reinterpret_cast<CallbackGeneric>(
&ThreadProcessDispatcher::NtOpenProcessTokenEx)};
// NOTE(liamjm): 2nd param is size_t: Using VOIDPTR_TYPE as they are
// the same size on windows.
static_assert(sizeof(size_t) == sizeof(void*),
"VOIDPTR_TYPE not same size as size_t");
static const IPCCall create_thread_params = {
{IpcTag::CREATETHREAD,
{VOIDPTR_TYPE, VOIDPTR_TYPE, VOIDPTR_TYPE, UINT32_TYPE}},
reinterpret_cast<CallbackGeneric>(
&ThreadProcessDispatcher::CreateThread)};
ipc_calls_.push_back(open_thread);
ipc_calls_.push_back(process_tokenex);
ipc_calls_.push_back(create_thread_params);
}
bool ThreadProcessDispatcher::SetupService(InterceptionManager* manager,
IpcTag service) {
switch (service) {
case IpcTag::NTOPENTHREAD:
case IpcTag::NTOPENPROCESSTOKENEX:
case IpcTag::CREATETHREAD:
// There is no explicit policy for these services.
// Intercepts are set up in SetupBasicInterceptions(), not here.
NOTREACHED_IN_MIGRATION();
return false;
default:
return false;
}
}
bool ThreadProcessDispatcher::NtOpenThread(IPCInfo* ipc,
uint32_t desired_access,
uint32_t thread_id) {
HANDLE handle;
NTSTATUS ret = ProcessPolicy::OpenThreadAction(
*ipc->client_info, desired_access, thread_id, &handle);
ipc->return_info.nt_status = ret;
ipc->return_info.handle = handle;
return true;
}
bool ThreadProcessDispatcher::NtOpenProcessTokenEx(IPCInfo* ipc,
HANDLE process,
uint32_t desired_access,
uint32_t attributes) {
HANDLE handle;
NTSTATUS ret = ProcessPolicy::OpenProcessTokenExAction(
*ipc->client_info, process, desired_access, attributes, &handle);
ipc->return_info.nt_status = ret;
ipc->return_info.handle = handle;
return true;
}
bool ThreadProcessDispatcher::CreateThread(IPCInfo* ipc,
SIZE_T stack_size,
LPTHREAD_START_ROUTINE start_address,
LPVOID parameter,
DWORD creation_flags) {
if (!start_address) {
return false;
}
HANDLE handle;
DWORD ret = ProcessPolicy::CreateThreadAction(*ipc->client_info, stack_size,
start_address, parameter,
creation_flags, &handle);
ipc->return_info.win32_result = ret;
ipc->return_info.handle = handle;
return true;
}
} // namespace sandbox