| Index: sandbox/win/src/process_thread_dispatcher.cc
|
| diff --git a/sandbox/win/src/process_thread_dispatcher.cc b/sandbox/win/src/process_thread_dispatcher.cc
|
| deleted file mode 100644
|
| index 886017c9a2cd26a30cc93759274c8730c078d87d..0000000000000000000000000000000000000000
|
| --- a/sandbox/win/src/process_thread_dispatcher.cc
|
| +++ /dev/null
|
| @@ -1,278 +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_dispatcher.h"
|
| -
|
| -#include <stddef.h>
|
| -#include <stdint.h>
|
| -
|
| -#include "base/logging.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 {
|
| -
|
| -// Extracts the application name from a command line.
|
| -//
|
| -// The application name is the first element of the command line. If
|
| -// there is no quotes, the first element is delimited by the first space.
|
| -// If there are quotes, the first element is delimited by the quotes.
|
| -//
|
| -// The create process call is smarter than us. It tries really hard to launch
|
| -// the process even if the command line is wrong. For example:
|
| -// "c:\program files\test param" will first try to launch c:\program.exe then
|
| -// c:\program files\test.exe. We don't do that, we stop after at the first
|
| -// space when there is no quotes.
|
| -base::string16 GetPathFromCmdLine(const base::string16 &cmd_line) {
|
| - base::string16 exe_name;
|
| - // Check if it starts with '"'.
|
| - if (cmd_line[0] == L'\"') {
|
| - // Find the position of the second '"', this terminates the path.
|
| - base::string16::size_type pos = cmd_line.find(L'\"', 1);
|
| - if (base::string16::npos == pos)
|
| - return cmd_line;
|
| - exe_name = cmd_line.substr(1, pos - 1);
|
| - } else {
|
| - // There is no '"', that means that the appname is terminated at the
|
| - // first space.
|
| - base::string16::size_type pos = cmd_line.find(L' ');
|
| - if (base::string16::npos == pos) {
|
| - // There is no space, the cmd_line contains only the app_name
|
| - exe_name = cmd_line;
|
| - } else {
|
| - exe_name = cmd_line.substr(0, pos);
|
| - }
|
| - }
|
| -
|
| - return exe_name;
|
| -}
|
| -
|
| -// Returns true is the path in parameter is relative. False if it's
|
| -// absolute.
|
| -bool IsPathRelative(const base::string16 &path) {
|
| - // A path is Relative if it's not a UNC path beginnning with \\ or a
|
| - // path beginning with a drive. (i.e. X:\)
|
| - if (path.find(L"\\\\") == 0 || path.find(L":\\") == 1)
|
| - return false;
|
| - return true;
|
| -}
|
| -
|
| -// Converts a relative path to an absolute path.
|
| -bool ConvertToAbsolutePath(const base::string16& child_current_directory,
|
| - bool use_env_path, base::string16 *path) {
|
| - wchar_t file_buffer[MAX_PATH];
|
| - wchar_t *file_part = NULL;
|
| -
|
| - // Here we should start by looking at the path where the child application was
|
| - // started. We don't have this information yet.
|
| - DWORD result = 0;
|
| - if (use_env_path) {
|
| - // Try with the complete path
|
| - result = ::SearchPath(NULL, path->c_str(), NULL, MAX_PATH, file_buffer,
|
| - &file_part);
|
| - }
|
| -
|
| - if (0 == result) {
|
| - // Try with the current directory of the child
|
| - result = ::SearchPath(child_current_directory.c_str(), path->c_str(), NULL,
|
| - MAX_PATH, file_buffer, &file_part);
|
| - }
|
| -
|
| - if (0 == result || result >= MAX_PATH)
|
| - return false;
|
| -
|
| - *path = file_buffer;
|
| - return true;
|
| -}
|
| -
|
| -} // namespace
|
| -namespace sandbox {
|
| -
|
| -ThreadProcessDispatcher::ThreadProcessDispatcher(PolicyBase* policy_base)
|
| - : policy_base_(policy_base) {
|
| - static const IPCCall open_thread = {
|
| - {IPC_NTOPENTHREAD_TAG, {UINT32_TYPE, UINT32_TYPE}},
|
| - reinterpret_cast<CallbackGeneric>(
|
| - &ThreadProcessDispatcher::NtOpenThread)};
|
| -
|
| - static const IPCCall open_process = {
|
| - {IPC_NTOPENPROCESS_TAG, {UINT32_TYPE, UINT32_TYPE}},
|
| - reinterpret_cast<CallbackGeneric>(
|
| - &ThreadProcessDispatcher::NtOpenProcess)};
|
| -
|
| - static const IPCCall process_token = {
|
| - {IPC_NTOPENPROCESSTOKEN_TAG, {VOIDPTR_TYPE, UINT32_TYPE}},
|
| - reinterpret_cast<CallbackGeneric>(
|
| - &ThreadProcessDispatcher::NtOpenProcessToken)};
|
| -
|
| - static const IPCCall process_tokenex = {
|
| - {IPC_NTOPENPROCESSTOKENEX_TAG, {VOIDPTR_TYPE, UINT32_TYPE, UINT32_TYPE}},
|
| - reinterpret_cast<CallbackGeneric>(
|
| - &ThreadProcessDispatcher::NtOpenProcessTokenEx)};
|
| -
|
| - static const IPCCall create_params = {
|
| - {IPC_CREATEPROCESSW_TAG,
|
| - {WCHAR_TYPE, WCHAR_TYPE, WCHAR_TYPE, INOUTPTR_TYPE}},
|
| - reinterpret_cast<CallbackGeneric>(
|
| - &ThreadProcessDispatcher::CreateProcessW)};
|
| -
|
| - // 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 = {
|
| - {IPC_CREATETHREAD_TAG,
|
| - {VOIDPTR_TYPE, VOIDPTR_TYPE, VOIDPTR_TYPE, UINT32_TYPE}},
|
| - reinterpret_cast<CallbackGeneric>(
|
| - &ThreadProcessDispatcher::CreateThread)};
|
| -
|
| - ipc_calls_.push_back(open_thread);
|
| - ipc_calls_.push_back(open_process);
|
| - ipc_calls_.push_back(process_token);
|
| - ipc_calls_.push_back(process_tokenex);
|
| - ipc_calls_.push_back(create_params);
|
| - ipc_calls_.push_back(create_thread_params);
|
| -}
|
| -
|
| -bool ThreadProcessDispatcher::SetupService(InterceptionManager* manager,
|
| - int service) {
|
| - switch (service) {
|
| - case IPC_NTOPENTHREAD_TAG:
|
| - case IPC_NTOPENPROCESS_TAG:
|
| - case IPC_NTOPENPROCESSTOKEN_TAG:
|
| - case IPC_NTOPENPROCESSTOKENEX_TAG:
|
| - case IPC_CREATETHREAD_TAG:
|
| - // There is no explicit policy for these services.
|
| - NOTREACHED();
|
| - return false;
|
| -
|
| - case IPC_CREATEPROCESSW_TAG:
|
| - return INTERCEPT_EAT(manager, kKerneldllName, CreateProcessW,
|
| - CREATE_PROCESSW_ID, 44) &&
|
| - INTERCEPT_EAT(manager, L"kernel32.dll", CreateProcessA,
|
| - CREATE_PROCESSA_ID, 44);
|
| -
|
| - 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::NtOpenProcess(IPCInfo* ipc,
|
| - uint32_t desired_access,
|
| - uint32_t process_id) {
|
| - HANDLE handle;
|
| - NTSTATUS ret = ProcessPolicy::OpenProcessAction(*ipc->client_info,
|
| - desired_access, process_id,
|
| - &handle);
|
| - ipc->return_info.nt_status = ret;
|
| - ipc->return_info.handle = handle;
|
| - return true;
|
| -}
|
| -
|
| -bool ThreadProcessDispatcher::NtOpenProcessToken(IPCInfo* ipc,
|
| - HANDLE process,
|
| - uint32_t desired_access) {
|
| - HANDLE handle;
|
| - NTSTATUS ret = ProcessPolicy::OpenProcessTokenAction(*ipc->client_info,
|
| - process, desired_access,
|
| - &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::CreateProcessW(IPCInfo* ipc, base::string16* name,
|
| - base::string16* cmd_line,
|
| - base::string16* cur_dir,
|
| - CountedBuffer* info) {
|
| - if (sizeof(PROCESS_INFORMATION) != info->Size())
|
| - return false;
|
| -
|
| - // Check if there is an application name.
|
| - base::string16 exe_name;
|
| - if (!name->empty())
|
| - exe_name = *name;
|
| - else
|
| - exe_name = GetPathFromCmdLine(*cmd_line);
|
| -
|
| - if (IsPathRelative(exe_name)) {
|
| - if (!ConvertToAbsolutePath(*cur_dir, name->empty(), &exe_name)) {
|
| - // Cannot find the path. Maybe the file does not exist.
|
| - ipc->return_info.win32_result = ERROR_FILE_NOT_FOUND;
|
| - return true;
|
| - }
|
| - }
|
| -
|
| - const wchar_t* const_exe_name = exe_name.c_str();
|
| - CountedParameterSet<NameBased> params;
|
| - params[NameBased::NAME] = ParamPickerMake(const_exe_name);
|
| -
|
| - EvalResult eval = policy_base_->EvalPolicy(IPC_CREATEPROCESSW_TAG,
|
| - params.GetBase());
|
| -
|
| - PROCESS_INFORMATION* proc_info =
|
| - reinterpret_cast<PROCESS_INFORMATION*>(info->Buffer());
|
| - // Here we force the app_name to be the one we used for the policy lookup.
|
| - // If our logic was wrong, at least we wont allow create a random process.
|
| - DWORD ret = ProcessPolicy::CreateProcessWAction(eval, *ipc->client_info,
|
| - exe_name, *cmd_line,
|
| - proc_info);
|
| -
|
| - ipc->return_info.win32_result = ret;
|
| - 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, NULL, &handle);
|
| -
|
| - ipc->return_info.nt_status = ret;
|
| - ipc->return_info.handle = handle;
|
| - return true;
|
| -}
|
| -
|
| -} // namespace sandbox
|
|
|