| Index: sandbox/win/src/process_thread_interception.cc
|
| diff --git a/sandbox/win/src/process_thread_interception.cc b/sandbox/win/src/process_thread_interception.cc
|
| deleted file mode 100644
|
| index 9cb20b9d717f875e81c077e7bd87d986f5a8e497..0000000000000000000000000000000000000000
|
| --- a/sandbox/win/src/process_thread_interception.cc
|
| +++ /dev/null
|
| @@ -1,488 +0,0 @@
|
| -// Copyright (c) 2013 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/process_thread_interception.h"
|
| -
|
| -#include <stdint.h>
|
| -#include "base/win/windows_version.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 {
|
| -
|
| -SANDBOX_INTERCEPT NtExports g_nt;
|
| -
|
| -// Hooks NtOpenThread and proxy the call to the broker if it's trying to
|
| -// open a thread in the same process.
|
| -NTSTATUS WINAPI TargetNtOpenThread(NtOpenThreadFunction orig_OpenThread,
|
| - PHANDLE thread, ACCESS_MASK desired_access,
|
| - POBJECT_ATTRIBUTES object_attributes,
|
| - PCLIENT_ID client_id) {
|
| - NTSTATUS status = orig_OpenThread(thread, desired_access, object_attributes,
|
| - client_id);
|
| - if (NT_SUCCESS(status))
|
| - return status;
|
| -
|
| - do {
|
| - if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
|
| - break;
|
| - if (!client_id)
|
| - break;
|
| -
|
| - uint32_t thread_id = 0;
|
| - bool should_break = false;
|
| - __try {
|
| - // We support only the calls for the current process
|
| - if (NULL != client_id->UniqueProcess)
|
| - should_break = true;
|
| -
|
| - // Object attributes should be NULL or empty.
|
| - if (!should_break && NULL != object_attributes) {
|
| - if (0 != object_attributes->Attributes ||
|
| - NULL != object_attributes->ObjectName ||
|
| - NULL != object_attributes->RootDirectory ||
|
| - NULL != object_attributes->SecurityDescriptor ||
|
| - NULL != object_attributes->SecurityQualityOfService) {
|
| - should_break = true;
|
| - }
|
| - }
|
| -
|
| - thread_id = static_cast<uint32_t>(
|
| - reinterpret_cast<ULONG_PTR>(client_id->UniqueThread));
|
| - } __except(EXCEPTION_EXECUTE_HANDLER) {
|
| - break;
|
| - }
|
| -
|
| - if (should_break)
|
| - break;
|
| -
|
| - if (!ValidParameter(thread, sizeof(HANDLE), WRITE))
|
| - break;
|
| -
|
| - void* memory = GetGlobalIPCMemory();
|
| - if (NULL == memory)
|
| - break;
|
| -
|
| - SharedMemIPCClient ipc(memory);
|
| - CrossCallReturn answer = {0};
|
| - ResultCode code = CrossCall(ipc, IPC_NTOPENTHREAD_TAG, desired_access,
|
| - thread_id, &answer);
|
| - if (SBOX_ALL_OK != code)
|
| - break;
|
| -
|
| - if (!NT_SUCCESS(answer.nt_status))
|
| - // The nt_status here is most likely STATUS_INVALID_CID because
|
| - // in the broker we set the process id in the CID (client ID) param
|
| - // to be the current process. If you try to open a thread from another
|
| - // process you will get this INVALID_CID error. On the other hand, if you
|
| - // try to open a thread in your own process, it should return success.
|
| - // We don't want to return STATUS_INVALID_CID here, so we return the
|
| - // return of the original open thread status, which is most likely
|
| - // STATUS_ACCESS_DENIED.
|
| - break;
|
| -
|
| - __try {
|
| - // Write the output parameters.
|
| - *thread = answer.handle;
|
| - } __except(EXCEPTION_EXECUTE_HANDLER) {
|
| - break;
|
| - }
|
| -
|
| - return answer.nt_status;
|
| - } while (false);
|
| -
|
| - return status;
|
| -}
|
| -
|
| -// Hooks NtOpenProcess and proxy the call to the broker if it's trying to
|
| -// open the current process.
|
| -NTSTATUS WINAPI TargetNtOpenProcess(NtOpenProcessFunction orig_OpenProcess,
|
| - PHANDLE process, ACCESS_MASK desired_access,
|
| - POBJECT_ATTRIBUTES object_attributes,
|
| - PCLIENT_ID client_id) {
|
| - NTSTATUS status = orig_OpenProcess(process, desired_access, object_attributes,
|
| - client_id);
|
| - if (NT_SUCCESS(status))
|
| - return status;
|
| -
|
| - do {
|
| - if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
|
| - break;
|
| - if (!client_id)
|
| - break;
|
| -
|
| - uint32_t process_id = 0;
|
| - bool should_break = false;
|
| - __try {
|
| - // Object attributes should be NULL or empty.
|
| - if (!should_break && NULL != object_attributes) {
|
| - if (0 != object_attributes->Attributes ||
|
| - NULL != object_attributes->ObjectName ||
|
| - NULL != object_attributes->RootDirectory ||
|
| - NULL != object_attributes->SecurityDescriptor ||
|
| - NULL != object_attributes->SecurityQualityOfService) {
|
| - should_break = true;
|
| - }
|
| - }
|
| -
|
| - process_id = static_cast<uint32_t>(
|
| - reinterpret_cast<ULONG_PTR>(client_id->UniqueProcess));
|
| - } __except(EXCEPTION_EXECUTE_HANDLER) {
|
| - break;
|
| - }
|
| -
|
| - if (should_break)
|
| - break;
|
| -
|
| - if (!ValidParameter(process, sizeof(HANDLE), WRITE))
|
| - break;
|
| -
|
| - void* memory = GetGlobalIPCMemory();
|
| - if (NULL == memory)
|
| - break;
|
| -
|
| - SharedMemIPCClient ipc(memory);
|
| - CrossCallReturn answer = {0};
|
| - ResultCode code = CrossCall(ipc, IPC_NTOPENPROCESS_TAG, desired_access,
|
| - process_id, &answer);
|
| - if (SBOX_ALL_OK != code)
|
| - break;
|
| -
|
| - if (!NT_SUCCESS(answer.nt_status))
|
| - return answer.nt_status;
|
| -
|
| - __try {
|
| - // Write the output parameters.
|
| - *process = answer.handle;
|
| - } __except(EXCEPTION_EXECUTE_HANDLER) {
|
| - break;
|
| - }
|
| -
|
| - return answer.nt_status;
|
| - } while (false);
|
| -
|
| - return status;
|
| -}
|
| -
|
| -
|
| -NTSTATUS WINAPI TargetNtOpenProcessToken(
|
| - NtOpenProcessTokenFunction orig_OpenProcessToken, HANDLE process,
|
| - ACCESS_MASK desired_access, PHANDLE token) {
|
| - NTSTATUS status = orig_OpenProcessToken(process, desired_access, token);
|
| - if (NT_SUCCESS(status))
|
| - return status;
|
| -
|
| - do {
|
| - if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
|
| - break;
|
| -
|
| - if (CURRENT_PROCESS != process)
|
| - break;
|
| -
|
| - if (!ValidParameter(token, sizeof(HANDLE), WRITE))
|
| - break;
|
| -
|
| - void* memory = GetGlobalIPCMemory();
|
| - if (NULL == memory)
|
| - break;
|
| -
|
| - SharedMemIPCClient ipc(memory);
|
| - CrossCallReturn answer = {0};
|
| - ResultCode code = CrossCall(ipc, IPC_NTOPENPROCESSTOKEN_TAG, process,
|
| - desired_access, &answer);
|
| - if (SBOX_ALL_OK != code)
|
| - break;
|
| -
|
| - if (!NT_SUCCESS(answer.nt_status))
|
| - return answer.nt_status;
|
| -
|
| - __try {
|
| - // Write the output parameters.
|
| - *token = answer.handle;
|
| - } __except(EXCEPTION_EXECUTE_HANDLER) {
|
| - break;
|
| - }
|
| -
|
| - return answer.nt_status;
|
| - } while (false);
|
| -
|
| - return status;
|
| -}
|
| -
|
| -NTSTATUS WINAPI TargetNtOpenProcessTokenEx(
|
| - NtOpenProcessTokenExFunction orig_OpenProcessTokenEx, HANDLE process,
|
| - ACCESS_MASK desired_access, ULONG handle_attributes, PHANDLE token) {
|
| - NTSTATUS status = orig_OpenProcessTokenEx(process, desired_access,
|
| - handle_attributes, token);
|
| - if (NT_SUCCESS(status))
|
| - return status;
|
| -
|
| - do {
|
| - if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
|
| - break;
|
| -
|
| - if (CURRENT_PROCESS != process)
|
| - break;
|
| -
|
| - if (!ValidParameter(token, sizeof(HANDLE), WRITE))
|
| - break;
|
| -
|
| - void* memory = GetGlobalIPCMemory();
|
| - if (NULL == memory)
|
| - break;
|
| -
|
| - SharedMemIPCClient ipc(memory);
|
| - CrossCallReturn answer = {0};
|
| - ResultCode code = CrossCall(ipc, IPC_NTOPENPROCESSTOKENEX_TAG, process,
|
| - desired_access, handle_attributes, &answer);
|
| - if (SBOX_ALL_OK != code)
|
| - break;
|
| -
|
| - if (!NT_SUCCESS(answer.nt_status))
|
| - return answer.nt_status;
|
| -
|
| - __try {
|
| - // Write the output parameters.
|
| - *token = answer.handle;
|
| - } __except(EXCEPTION_EXECUTE_HANDLER) {
|
| - break;
|
| - }
|
| -
|
| - return answer.nt_status;
|
| - } while (false);
|
| -
|
| - return status;
|
| -}
|
| -
|
| -BOOL WINAPI TargetCreateProcessW(CreateProcessWFunction orig_CreateProcessW,
|
| - LPCWSTR application_name, LPWSTR command_line,
|
| - LPSECURITY_ATTRIBUTES process_attributes,
|
| - LPSECURITY_ATTRIBUTES thread_attributes,
|
| - BOOL inherit_handles, DWORD flags,
|
| - LPVOID environment, LPCWSTR current_directory,
|
| - LPSTARTUPINFOW startup_info,
|
| - LPPROCESS_INFORMATION process_information) {
|
| - if (SandboxFactory::GetTargetServices()->GetState()->IsCsrssConnected() &&
|
| - orig_CreateProcessW(application_name, command_line, process_attributes,
|
| - thread_attributes, inherit_handles, flags,
|
| - environment, current_directory, startup_info,
|
| - process_information)) {
|
| - return TRUE;
|
| - }
|
| -
|
| - // We don't trust that the IPC can work this early.
|
| - if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
|
| - return FALSE;
|
| -
|
| - // Don't call GetLastError before InitCalled() succeeds because kernel32 may
|
| - // not be mapped yet.
|
| - DWORD original_error = ::GetLastError();
|
| -
|
| - do {
|
| - if (!ValidParameter(process_information, sizeof(PROCESS_INFORMATION),
|
| - WRITE))
|
| - break;
|
| -
|
| - void* memory = GetGlobalIPCMemory();
|
| - if (NULL == memory)
|
| - break;
|
| -
|
| - const wchar_t* cur_dir = NULL;
|
| -
|
| - wchar_t current_directory[MAX_PATH];
|
| - DWORD result = ::GetCurrentDirectory(MAX_PATH, current_directory);
|
| - if (0 != result && result < MAX_PATH)
|
| - cur_dir = current_directory;
|
| -
|
| - SharedMemIPCClient ipc(memory);
|
| - CrossCallReturn answer = {0};
|
| -
|
| - InOutCountedBuffer proc_info(process_information,
|
| - sizeof(PROCESS_INFORMATION));
|
| -
|
| - ResultCode code = CrossCall(ipc, IPC_CREATEPROCESSW_TAG, application_name,
|
| - command_line, cur_dir, proc_info, &answer);
|
| - if (SBOX_ALL_OK != code)
|
| - break;
|
| -
|
| - ::SetLastError(answer.win32_result);
|
| - if (ERROR_SUCCESS != answer.win32_result)
|
| - return FALSE;
|
| -
|
| - return TRUE;
|
| - } while (false);
|
| -
|
| - ::SetLastError(original_error);
|
| - return FALSE;
|
| -}
|
| -
|
| -BOOL WINAPI TargetCreateProcessA(CreateProcessAFunction orig_CreateProcessA,
|
| - LPCSTR application_name, LPSTR command_line,
|
| - LPSECURITY_ATTRIBUTES process_attributes,
|
| - LPSECURITY_ATTRIBUTES thread_attributes,
|
| - BOOL inherit_handles, DWORD flags,
|
| - LPVOID environment, LPCSTR current_directory,
|
| - LPSTARTUPINFOA startup_info,
|
| - LPPROCESS_INFORMATION process_information) {
|
| - if (SandboxFactory::GetTargetServices()->GetState()->IsCsrssConnected() &&
|
| - orig_CreateProcessA(application_name, command_line, process_attributes,
|
| - thread_attributes, inherit_handles, flags,
|
| - environment, current_directory, startup_info,
|
| - process_information)) {
|
| - return TRUE;
|
| - }
|
| -
|
| - // We don't trust that the IPC can work this early.
|
| - if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
|
| - return FALSE;
|
| -
|
| - // Don't call GetLastError before InitCalled() succeeds because kernel32 may
|
| - // not be mapped yet.
|
| - DWORD original_error = ::GetLastError();
|
| -
|
| - do {
|
| - if (!ValidParameter(process_information, sizeof(PROCESS_INFORMATION),
|
| - WRITE))
|
| - break;
|
| -
|
| - void* memory = GetGlobalIPCMemory();
|
| - if (NULL == memory)
|
| - break;
|
| -
|
| - // Convert the input params to unicode.
|
| - UNICODE_STRING *cmd_unicode = NULL;
|
| - UNICODE_STRING *app_unicode = NULL;
|
| - if (command_line) {
|
| - cmd_unicode = AnsiToUnicode(command_line);
|
| - if (!cmd_unicode)
|
| - break;
|
| - }
|
| -
|
| - if (application_name) {
|
| - app_unicode = AnsiToUnicode(application_name);
|
| - if (!app_unicode) {
|
| - operator delete(cmd_unicode, NT_ALLOC);
|
| - break;
|
| - }
|
| - }
|
| -
|
| - const wchar_t* cmd_line = cmd_unicode ? cmd_unicode->Buffer : NULL;
|
| - const wchar_t* app_name = app_unicode ? app_unicode->Buffer : NULL;
|
| - const wchar_t* cur_dir = NULL;
|
| -
|
| - wchar_t current_directory[MAX_PATH];
|
| - DWORD result = ::GetCurrentDirectory(MAX_PATH, current_directory);
|
| - if (0 != result && result < MAX_PATH)
|
| - cur_dir = current_directory;
|
| -
|
| - SharedMemIPCClient ipc(memory);
|
| - CrossCallReturn answer = {0};
|
| -
|
| - InOutCountedBuffer proc_info(process_information,
|
| - sizeof(PROCESS_INFORMATION));
|
| -
|
| - ResultCode code = CrossCall(ipc, IPC_CREATEPROCESSW_TAG, app_name,
|
| - cmd_line, cur_dir, proc_info, &answer);
|
| -
|
| - operator delete(cmd_unicode, NT_ALLOC);
|
| - operator delete(app_unicode, NT_ALLOC);
|
| -
|
| - if (SBOX_ALL_OK != code)
|
| - break;
|
| -
|
| - ::SetLastError(answer.win32_result);
|
| - if (ERROR_SUCCESS != answer.win32_result)
|
| - return FALSE;
|
| -
|
| - return TRUE;
|
| - } while (false);
|
| -
|
| - ::SetLastError(original_error);
|
| - return FALSE;
|
| -}
|
| -
|
| -HANDLE WINAPI TargetCreateThread(CreateThreadFunction orig_CreateThread,
|
| - LPSECURITY_ATTRIBUTES thread_attributes,
|
| - SIZE_T stack_size,
|
| - LPTHREAD_START_ROUTINE start_address,
|
| - LPVOID parameter,
|
| - DWORD creation_flags,
|
| - LPDWORD thread_id) {
|
| - HANDLE hThread = NULL;
|
| -
|
| - TargetServices* target_services = SandboxFactory::GetTargetServices();
|
| - if (NULL == target_services ||
|
| - target_services->GetState()->IsCsrssConnected()) {
|
| - hThread = orig_CreateThread(thread_attributes, stack_size, start_address,
|
| - parameter, creation_flags, thread_id);
|
| - if (hThread) {
|
| - return hThread;
|
| - }
|
| - }
|
| -
|
| - DWORD original_error = ::GetLastError();
|
| - do {
|
| - if (NULL == target_services)
|
| - break;
|
| -
|
| - // We don't trust that the IPC can work this early.
|
| - if (!target_services->GetState()->InitCalled())
|
| - break;
|
| -
|
| - __try {
|
| - if (NULL != thread_id &&
|
| - !ValidParameter(thread_id, sizeof(*thread_id), WRITE))
|
| - break;
|
| -
|
| - if (nullptr == start_address)
|
| - break;
|
| - // We don't support thread_attributes not being null.
|
| - if (nullptr != thread_attributes)
|
| - break;
|
| - } __except (EXCEPTION_EXECUTE_HANDLER) {
|
| - break;
|
| - }
|
| -
|
| - void* memory = GetGlobalIPCMemory();
|
| - if (nullptr == memory)
|
| - break;
|
| -
|
| - SharedMemIPCClient ipc(memory);
|
| - CrossCallReturn answer = {0};
|
| -
|
| - // NOTE: we don't pass the thread_attributes through. This matches the
|
| - // approach in CreateProcess and in CreateThreadInternal().
|
| - ResultCode code = CrossCall(ipc, IPC_CREATETHREAD_TAG,
|
| - reinterpret_cast<LPVOID>(stack_size),
|
| - reinterpret_cast<LPVOID>(start_address),
|
| - parameter, creation_flags, &answer);
|
| - if (SBOX_ALL_OK != code)
|
| - break;
|
| -
|
| - ::SetLastError(answer.win32_result);
|
| - if (ERROR_SUCCESS != answer.win32_result) {
|
| - return NULL;
|
| - }
|
| -
|
| - __try {
|
| - if (thread_id != NULL) {
|
| - *thread_id = ::GetThreadId(answer.handle);
|
| - }
|
| - return answer.handle;
|
| - } __except (EXCEPTION_EXECUTE_HANDLER) {
|
| - break;
|
| - }
|
| - } while (false);
|
| -
|
| - ::SetLastError(original_error);
|
| - return NULL;
|
| -}
|
| -
|
| -} // namespace sandbox
|
|
|