15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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/tests/common/controller.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/process.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/sys_string_conversions.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_factory.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kDefaultTimeout = 60000; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constructs a full path to a file inside the system32 folder. 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MakePathToSys32(const wchar_t* name, bool is_obj_man_path) { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wchar_t windows_path[MAX_PATH] = {0}; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == ::GetSystemWindowsDirectoryW(windows_path, MAX_PATH)) 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::string16(); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 full_path(windows_path); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (full_path.empty()) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return full_path; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_obj_man_path) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_path.insert(0, L"\\??\\"); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_path += L"\\system32\\"; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_path += name; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return full_path; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constructs a full path to a file inside the syswow64 folder. 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MakePathToSysWow64(const wchar_t* name, bool is_obj_man_path) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wchar_t windows_path[MAX_PATH] = {0}; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == ::GetSystemWindowsDirectoryW(windows_path, MAX_PATH)) 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::string16(); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 full_path(windows_path); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (full_path.empty()) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return full_path; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_obj_man_path) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_path.insert(0, L"\\??\\"); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_path += L"\\SysWOW64\\"; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_path += name; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return full_path; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsProcessRunning(HANDLE process) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD exit_code = 0; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::GetExitCodeProcess(process, &exit_code)) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return exit_code == STILL_ACTIVE; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MakePathToSys(const wchar_t* name, bool is_obj_man_path) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (base::win::OSInfo::GetInstance()->wow64_status() == 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::OSInfo::WOW64_ENABLED) ? 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakePathToSysWow64(name, is_obj_man_path) : 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakePathToSys32(name, is_obj_man_path); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrokerServices* GetBroker() { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static BrokerServices* broker = SandboxFactory::GetBrokerServices(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool is_initialized = false; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!broker) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_initialized) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SBOX_ALL_OK != broker->Init()) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_initialized = true; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return broker; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestRunner::TestRunner(JobLevel job_level, TokenLevel startup_token, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TokenLevel main_token) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : is_init_(false), is_async_(false), no_sandbox_(false), 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_process_id_(0) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Init(job_level, startup_token, main_token); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestRunner::TestRunner() 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : is_init_(false), is_async_(false), no_sandbox_(false), 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_process_id_(0) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Init(JOB_LOCKDOWN, USER_RESTRICTED_SAME_ACCESS, USER_LOCKDOWN); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestRunner::Init(JobLevel job_level, TokenLevel startup_token, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TokenLevel main_token) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) broker_ = NULL; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy_ = NULL; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_ = kDefaultTimeout; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = AFTER_REVERT; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_async_= false; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kill_on_destruction_ = true; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_process_id_ = 0; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) broker_ = GetBroker(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!broker_) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy_ = broker_->CreatePolicy(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!policy_) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy_->SetJobLevel(job_level, 0); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy_->SetTokenLevel(startup_token, main_token); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_init_ = true; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TargetPolicy* TestRunner::GetPolicy() { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return policy_; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestRunner::~TestRunner() { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_process_ && kill_on_destruction_) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::TerminateProcess(target_process_, 0); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (policy_) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy_->Release(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestRunner::AddRule(TargetPolicy::SubSystem subsystem, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TargetPolicy::Semantics semantics, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* pattern) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_init_) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (SBOX_ALL_OK == policy_->AddRule(subsystem, semantics, pattern)); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestRunner::AddRuleSys32(TargetPolicy::Semantics semantics, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* pattern) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_init_) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 win32_path = MakePathToSys32(pattern, false); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (win32_path.empty()) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!AddRule(TargetPolicy::SUBSYS_FILES, semantics, win32_path.c_str())) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::win::OSInfo::GetInstance()->wow64_status() != 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::OSInfo::WOW64_ENABLED) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) win32_path = MakePathToSysWow64(pattern, false); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (win32_path.empty()) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddRule(TargetPolicy::SUBSYS_FILES, semantics, win32_path.c_str()); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestRunner::AddFsRule(TargetPolicy::Semantics semantics, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* pattern) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_init_) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddRule(TargetPolicy::SUBSYS_FILES, semantics, pattern); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TestRunner::RunTest(const wchar_t* command) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (MAX_STATE > 10) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_INVALID_PARAMETER; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wchar_t state_number[2]; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_number[0] = L'0' + state_; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_number[1] = L'\0'; 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 full_command(state_number); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_command += L" "; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_command += command; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return InternalRunTest(full_command.c_str()); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TestRunner::InternalRunTest(const wchar_t* command) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_init_) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_FAILED_TO_RUN_TEST; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For simplicity TestRunner supports only one process per instance. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_process_) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsProcessRunning(target_process_)) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_FAILED_TO_RUN_TEST; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_process_.Close(); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_process_id_ = 0; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the path to the sandboxed process. 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wchar_t prog_name[MAX_PATH]; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModuleFileNameW(NULL, prog_name, MAX_PATH); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Launch the sandboxed process. 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResultCode result = SBOX_ALL_OK; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PROCESS_INFORMATION target = {0}; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 arguments(L"\""); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arguments += prog_name; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arguments += L"\" -child"; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arguments += no_sandbox_ ? L"-no-sandbox " : L" "; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arguments += command; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (no_sandbox_) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STARTUPINFO startup_info = {sizeof(STARTUPINFO)}; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!::CreateProcessW(prog_name, &arguments[0], NULL, NULL, FALSE, 0, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, NULL, &startup_info, &target)) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_ERROR_GENERIC; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) broker_->AddTargetPeer(target.hProcess); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = broker_->SpawnTarget(prog_name, arguments.c_str(), policy_, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &target); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SBOX_ALL_OK != result) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_FAILED_TO_RUN_TEST; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::ResumeThread(target.hThread); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For an asynchronous run we don't bother waiting. 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_async_) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_process_.Set(target.hProcess); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_process_id_ = target.dwProcessId; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::CloseHandle(target.hThread); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_SUCCEEDED; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::IsDebuggerPresent()) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't kill the target process on a time-out while we are debugging. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_ = INFINITE; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (WAIT_TIMEOUT == ::WaitForSingleObject(target.hProcess, timeout_)) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::TerminateProcess(target.hProcess, SBOX_TEST_TIMED_OUT); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::CloseHandle(target.hProcess); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::CloseHandle(target.hThread); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_TIMED_OUT; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD exit_code = SBOX_TEST_LAST_RESULT; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!::GetExitCodeProcess(target.hProcess, &exit_code)) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::CloseHandle(target.hProcess); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::CloseHandle(target.hThread); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_FAILED_TO_RUN_TEST; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::CloseHandle(target.hProcess); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::CloseHandle(target.hThread); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return exit_code; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestRunner::SetTimeout(DWORD timeout_ms) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_ = timeout_ms; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestRunner::SetTestState(SboxTestsState desired_state) { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = desired_state; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is the main procedure for the target (child) application. We'll find out 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the target test and call it. 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We expect the arguments to be: 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// argv[1] = "-child" 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// argv[2] = SboxTestsState when to run the command 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// argv[3] = command to run 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// argv[4...] = command arguments. 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int DispatchCall(int argc, wchar_t **argv) { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (argc < 4) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_INVALID_PARAMETER; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hard code two tests to avoid dispatch failures. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == _wcsicmp(argv[3], L"wait")) { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Sleep(INFINITE); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_TIMED_OUT; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == _wcsicmp(argv[3], L"ping")) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_PING_OK; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SboxTestsState state = static_cast<SboxTestsState>(_wtoi(argv[2])); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((state <= MIN_STATE) || (state >= MAX_STATE)) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_INVALID_PARAMETER; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMODULE module; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<wchar_t*>(&DispatchCall), &module)) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string command_name = base::SysWideToMultiByte(argv[3], CP_UTF8); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandFunction command = reinterpret_cast<CommandFunction>( 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetProcAddress(module, command_name.c_str())); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!command) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (BEFORE_INIT == state) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return command(argc - 4, argv + 4); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (EVERY_STATE == state) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command(argc - 4, argv + 4); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TargetServices* target = SandboxFactory::GetTargetServices(); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target) { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SBOX_ALL_OK != target->Init()) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (BEFORE_REVERT == state) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return command(argc - 4, argv + 4); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (EVERY_STATE == state) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command(argc - 4, argv + 4); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target->LowerToken(); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (0 != _wcsicmp(argv[1], L"-child-no-sandbox")) { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return command(argc - 4, argv + 4); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sandbox 337