18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/process_thread_dispatcher.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/crosscall_client.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/interception.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/interceptors.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/ipc_tags.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_broker.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_params.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/process_thread_interception.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/process_thread_policy.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Extracts the application name from a command line.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The application name is the first element of the command line. If
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// there is no quotes, the first element is delimited by the first space.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If there are quotes, the first element is delimited by the quotes.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The create process call is smarter than us. It tries really hard to launch
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the process even if the command line is wrong. For example:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "c:\program files\test param" will first try to launch c:\program.exe then
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// c:\program files\test.exe. We don't do that, we stop after at the first
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// space when there is no quotes.
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 GetPathFromCmdLine(const base::string16 &cmd_line) {
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 exe_name;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if it starts with '"'.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cmd_line[0] == L'\"') {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Find the position of the second '"', this terminates the path.
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::string16::size_type pos = cmd_line.find(L'\"', 1);
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (base::string16::npos == pos)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return cmd_line;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exe_name = cmd_line.substr(1, pos - 1);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // There is no '"', that means that the appname is terminated at the
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // first space.
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::string16::size_type pos = cmd_line.find(L' ');
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (base::string16::npos == pos) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // There is no space, the cmd_line contains only the app_name
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      exe_name = cmd_line;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      exe_name = cmd_line.substr(0, pos);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return exe_name;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true is the path in parameter is relative. False if it's
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// absolute.
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool IsPathRelative(const base::string16 &path) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A path is Relative if it's not a UNC path beginnning with \\ or a
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // path beginning with a drive. (i.e. X:\)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (path.find(L"\\\\") == 0 || path.find(L":\\") == 1)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts a relative path to an absolute path.
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ConvertToAbsolutePath(const base::string16& child_current_directory,
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           bool use_env_path, base::string16 *path) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wchar_t file_buffer[MAX_PATH];
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wchar_t *file_part = NULL;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Here we should start by looking at the path where the child application was
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // started. We don't have this information yet.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD result = 0;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (use_env_path) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Try with the complete path
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = ::SearchPath(NULL, path->c_str(), NULL, MAX_PATH, file_buffer,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          &file_part);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (0 == result) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Try with the current directory of the child
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = ::SearchPath(child_current_directory.c_str(), path->c_str(), NULL,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          MAX_PATH, file_buffer, &file_part);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (0 == result || result >= MAX_PATH)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *path = file_buffer;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ThreadProcessDispatcher::ThreadProcessDispatcher(PolicyBase* policy_base)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : policy_base_(policy_base) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const IPCCall open_thread = {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {IPC_NTOPENTHREAD_TAG, ULONG_TYPE, ULONG_TYPE},
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reinterpret_cast<CallbackGeneric>(
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &ThreadProcessDispatcher::NtOpenThread)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const IPCCall open_process = {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {IPC_NTOPENPROCESS_TAG, ULONG_TYPE, ULONG_TYPE},
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reinterpret_cast<CallbackGeneric>(
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &ThreadProcessDispatcher::NtOpenProcess)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const IPCCall process_token = {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {IPC_NTOPENPROCESSTOKEN_TAG, VOIDPTR_TYPE, ULONG_TYPE},
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reinterpret_cast<CallbackGeneric>(
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &ThreadProcessDispatcher::NtOpenProcessToken)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const IPCCall process_tokenex = {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {IPC_NTOPENPROCESSTOKENEX_TAG, VOIDPTR_TYPE, ULONG_TYPE, ULONG_TYPE},
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reinterpret_cast<CallbackGeneric>(
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &ThreadProcessDispatcher::NtOpenProcessTokenEx)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const IPCCall create_params = {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {IPC_CREATEPROCESSW_TAG, WCHAR_TYPE, WCHAR_TYPE, WCHAR_TYPE, INOUTPTR_TYPE},
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reinterpret_cast<CallbackGeneric>(
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &ThreadProcessDispatcher::CreateProcessW)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc_calls_.push_back(open_thread);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc_calls_.push_back(open_process);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc_calls_.push_back(process_token);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc_calls_.push_back(process_tokenex);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc_calls_.push_back(create_params);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThreadProcessDispatcher::SetupService(InterceptionManager* manager,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           int service) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (service) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IPC_NTOPENTHREAD_TAG:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IPC_NTOPENPROCESS_TAG:
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IPC_NTOPENPROCESSTOKEN_TAG:
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IPC_NTOPENPROCESSTOKENEX_TAG:
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // There is no explicit policy for these services.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IPC_CREATEPROCESSW_TAG:
1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return INTERCEPT_EAT(manager, kKerneldllName, CreateProcessW,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           CREATE_PROCESSW_ID, 44) &&
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             INTERCEPT_EAT(manager, L"kernel32.dll", CreateProcessA,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           CREATE_PROCESSA_ID, 44);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThreadProcessDispatcher::NtOpenThread(IPCInfo* ipc, DWORD desired_access,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           DWORD thread_id) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE handle;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NTSTATUS ret = ProcessPolicy::OpenThreadAction(*ipc->client_info,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 desired_access, thread_id,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 &handle);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc->return_info.nt_status = ret;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc->return_info.handle = handle;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThreadProcessDispatcher::NtOpenProcess(IPCInfo* ipc, DWORD desired_access,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            DWORD process_id) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE handle;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NTSTATUS ret = ProcessPolicy::OpenProcessAction(*ipc->client_info,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  desired_access, process_id,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  &handle);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc->return_info.nt_status = ret;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc->return_info.handle = handle;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThreadProcessDispatcher::NtOpenProcessToken(IPCInfo* ipc, HANDLE process,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 DWORD desired_access) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE handle;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NTSTATUS ret = ProcessPolicy::OpenProcessTokenAction(*ipc->client_info,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       process, desired_access,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       &handle);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc->return_info.nt_status = ret;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc->return_info.handle = handle;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ThreadProcessDispatcher::NtOpenProcessTokenEx(IPCInfo* ipc, HANDLE process,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   DWORD desired_access,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   DWORD attributes) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE handle;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NTSTATUS ret = ProcessPolicy::OpenProcessTokenExAction(*ipc->client_info,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         process,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         desired_access,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         attributes, &handle);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc->return_info.nt_status = ret;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc->return_info.handle = handle;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ThreadProcessDispatcher::CreateProcessW(IPCInfo* ipc, base::string16* name,
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             base::string16* cmd_line,
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             base::string16* cur_dir,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             CountedBuffer* info) {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (sizeof(PROCESS_INFORMATION) != info->Size())
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if there is an application name.
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 exe_name;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!name->empty())
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exe_name = *name;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exe_name = GetPathFromCmdLine(*cmd_line);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsPathRelative(exe_name)) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ConvertToAbsolutePath(*cur_dir, name->empty(), &exe_name)) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Cannot find the path. Maybe the file does not exist.
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ipc->return_info.win32_result = ERROR_FILE_NOT_FOUND;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t* const_exe_name = exe_name.c_str();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CountedParameterSet<NameBased> params;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params[NameBased::NAME] = ParamPickerMake(const_exe_name);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EvalResult eval = policy_base_->EvalPolicy(IPC_CREATEPROCESSW_TAG,
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             params.GetBase());
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PROCESS_INFORMATION* proc_info =
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<PROCESS_INFORMATION*>(info->Buffer());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Here we force the app_name to be the one we used for the policy lookup.
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If our logic was wrong, at least we wont allow create a random process.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD ret = ProcessPolicy::CreateProcessWAction(eval, *ipc->client_info,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  exe_name, *cmd_line,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  proc_info);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ipc->return_info.win32_result = ret;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace sandbox
246