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)#ifndef SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string16.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_handle.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See winerror.h for details. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SEVERITY_INFO_FLAGS 0x40000000 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SEVERITY_ERROR_FLAGS 0xC0000000 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CUSTOMER_CODE 0x20000000 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SBOX_TESTS_FACILITY 0x05B10000 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All the possible error codes returned by the child process in 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the sandbox. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum SboxTestResult { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_FIRST_RESULT = CUSTOMER_CODE | SBOX_TESTS_FACILITY, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_SUCCEEDED, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_PING_OK, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_FIRST_INFO = SBOX_TEST_FIRST_RESULT | SEVERITY_INFO_FLAGS, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_DENIED, // Access was denied. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_NOT_FOUND, // The resource was not found. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_FIRST_ERROR = SBOX_TEST_FIRST_RESULT | SEVERITY_ERROR_FLAGS, 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_SECOND_ERROR, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_THIRD_ERROR, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_FOURTH_ERROR, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_FIFTH_ERROR, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_SIXTH_ERROR, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_SEVENTH_ERROR, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_INVALID_PARAMETER, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_FAILED_TO_RUN_TEST, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_FAILED_TO_EXECUTE_COMMAND, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_TIMED_OUT, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_FAILED, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SBOX_TEST_LAST_RESULT 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool IsSboxTestsResult(SboxTestResult result) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int code = static_cast<unsigned int>(result); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int first = static_cast<unsigned int>(SBOX_TEST_FIRST_RESULT); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int last = static_cast<unsigned int>(SBOX_TEST_LAST_RESULT); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (code > first) && (code < last); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum SboxTestsState { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MIN_STATE = 1, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BEFORE_INIT, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BEFORE_REVERT, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AFTER_REVERT, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVERY_STATE, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAX_STATE 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SBOX_TESTS_API __declspec(dllexport) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SBOX_TESTS_COMMAND extern "C" SBOX_TESTS_API 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int (*CommandFunction)(int argc, wchar_t **argv); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Class to facilitate the launch of a test inside the sandbox. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestRunner { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestRunner(JobLevel job_level, TokenLevel startup_token, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TokenLevel main_token); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestRunner(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~TestRunner(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds a rule to the policy. The parameters are the same as the AddRule 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function in the sandbox. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddRule(TargetPolicy::SubSystem subsystem, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TargetPolicy::Semantics semantics, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* pattern); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds a filesystem rules with the path of a file in system32. The function 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // appends "pattern" to "system32" and then call AddRule. Return true if the 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function succeeds. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddRuleSys32(TargetPolicy::Semantics semantics, const wchar_t* pattern); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds a filesystem rules to the policy. Returns true if the functions 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // succeeds. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddFsRule(TargetPolicy::Semantics semantics, const wchar_t* pattern); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Starts a child process in the sandbox and ask it to run |command|. Returns 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a SboxTestResult. By default, the test runs AFTER_REVERT. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int RunTest(const wchar_t* command); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets the timeout value for the child to run the command and return. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetTimeout(DWORD timeout_ms); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets TestRunner to return without waiting for the process to exit. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetAsynchronous(bool is_async) { is_async_ = is_async; } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets TestRunner to return without waiting for the process to exit. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetUnsandboxed(bool is_no_sandbox) { no_sandbox_ = is_no_sandbox; } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets the desired state for the test to run. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetTestState(SboxTestsState desired_state); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets a flag whether the process should be killed when the TestRunner is 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destroyed. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetKillOnDestruction(bool value) { kill_on_destruction_ = value; } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the pointers to the policy object. It can be used to modify 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the policy manually. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TargetPolicy* GetPolicy(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrokerServices* broker() { return broker_; } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the process handle for an asynchronous test. 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci HANDLE process() { return target_process_.Get(); } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the process ID for an asynchronous test. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD process_id() { return target_process_id_; } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes the data in the object. Sets is_init_ to tree if the 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function succeeds. This is meant to be called from the constructor. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Init(JobLevel job_level, TokenLevel startup_token, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TokenLevel main_token); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The actual runner. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int InternalRunTest(const wchar_t* command); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrokerServices* broker_; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TargetPolicy* policy_; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD timeout_; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SboxTestsState state_; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_init_; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_async_; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool no_sandbox_; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool kill_on_destruction_; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedHandle target_process_; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD target_process_id_; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the broker services. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrokerServices* GetBroker(); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constructs a full path to a file inside the system32 (or syswow64) folder. 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MakePathToSys(const wchar_t* name, bool is_obj_man_path); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Runs the given test on the target process. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int DispatchCall(int argc, wchar_t **argv); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sandbox 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_ 160