1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_ 6 #define SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_ 7 8 #include <windows.h> 9 #include <string> 10 11 #include "base/win/scoped_handle.h" 12 #include "sandbox/win/src/sandbox.h" 13 14 namespace sandbox { 15 16 // See winerror.h for details. 17 #define SEVERITY_INFO_FLAGS 0x40000000 18 #define SEVERITY_ERROR_FLAGS 0xC0000000 19 #define CUSTOMER_CODE 0x20000000 20 #define SBOX_TESTS_FACILITY 0x05B10000 21 22 // All the possible error codes returned by the child process in 23 // the sandbox. 24 enum SboxTestResult { 25 SBOX_TEST_FIRST_RESULT = CUSTOMER_CODE | SBOX_TESTS_FACILITY, 26 SBOX_TEST_SUCCEEDED, 27 SBOX_TEST_PING_OK, 28 SBOX_TEST_FIRST_INFO = SBOX_TEST_FIRST_RESULT | SEVERITY_INFO_FLAGS, 29 SBOX_TEST_DENIED, // Access was denied. 30 SBOX_TEST_NOT_FOUND, // The resource was not found. 31 SBOX_TEST_FIRST_ERROR = SBOX_TEST_FIRST_RESULT | SEVERITY_ERROR_FLAGS, 32 SBOX_TEST_SECOND_ERROR, 33 SBOX_TEST_THIRD_ERROR, 34 SBOX_TEST_FOURTH_ERROR, 35 SBOX_TEST_FIFTH_ERROR, 36 SBOX_TEST_SIXTH_ERROR, 37 SBOX_TEST_SEVENTH_ERROR, 38 SBOX_TEST_INVALID_PARAMETER, 39 SBOX_TEST_FAILED_TO_RUN_TEST, 40 SBOX_TEST_FAILED_TO_EXECUTE_COMMAND, 41 SBOX_TEST_TIMED_OUT, 42 SBOX_TEST_FAILED, 43 SBOX_TEST_LAST_RESULT 44 }; 45 46 inline bool IsSboxTestsResult(SboxTestResult result) { 47 unsigned int code = static_cast<unsigned int>(result); 48 unsigned int first = static_cast<unsigned int>(SBOX_TEST_FIRST_RESULT); 49 unsigned int last = static_cast<unsigned int>(SBOX_TEST_LAST_RESULT); 50 return (code > first) && (code < last); 51 } 52 53 enum SboxTestsState { 54 MIN_STATE = 1, 55 BEFORE_INIT, 56 BEFORE_REVERT, 57 AFTER_REVERT, 58 EVERY_STATE, 59 MAX_STATE 60 }; 61 62 #define SBOX_TESTS_API __declspec(dllexport) 63 #define SBOX_TESTS_COMMAND extern "C" SBOX_TESTS_API 64 65 extern "C" { 66 typedef int (*CommandFunction)(int argc, wchar_t **argv); 67 } 68 69 // Class to facilitate the launch of a test inside the sandbox. 70 class TestRunner { 71 public: 72 TestRunner(JobLevel job_level, TokenLevel startup_token, 73 TokenLevel main_token); 74 75 TestRunner(); 76 77 ~TestRunner(); 78 79 // Adds a rule to the policy. The parameters are the same as the AddRule 80 // function in the sandbox. 81 bool AddRule(TargetPolicy::SubSystem subsystem, 82 TargetPolicy::Semantics semantics, 83 const wchar_t* pattern); 84 85 // Adds a filesystem rules with the path of a file in system32. The function 86 // appends "pattern" to "system32" and then call AddRule. Return true if the 87 // function succeeds. 88 bool AddRuleSys32(TargetPolicy::Semantics semantics, const wchar_t* pattern); 89 90 // Adds a filesystem rules to the policy. Returns true if the functions 91 // succeeds. 92 bool AddFsRule(TargetPolicy::Semantics semantics, const wchar_t* pattern); 93 94 // Starts a child process in the sandbox and ask it to run |command|. Returns 95 // a SboxTestResult. By default, the test runs AFTER_REVERT. 96 int RunTest(const wchar_t* command); 97 98 // Sets the timeout value for the child to run the command and return. 99 void SetTimeout(DWORD timeout_ms); 100 101 // Sets TestRunner to return without waiting for the process to exit. 102 void SetAsynchronous(bool is_async) { is_async_ = is_async; } 103 104 // Sets TestRunner to return without waiting for the process to exit. 105 void SetUnsandboxed(bool is_no_sandbox) { no_sandbox_ = is_no_sandbox; } 106 107 // Sets the desired state for the test to run. 108 void SetTestState(SboxTestsState desired_state); 109 110 // Sets a flag whether the process should be killed when the TestRunner is 111 // destroyed. 112 void SetKillOnDestruction(bool value) { kill_on_destruction_ = value; } 113 114 // Returns the pointers to the policy object. It can be used to modify 115 // the policy manually. 116 TargetPolicy* GetPolicy(); 117 118 BrokerServices* broker() { return broker_; } 119 120 // Returns the process handle for an asynchronous test. 121 HANDLE process() { return target_process_; } 122 123 // Returns the process ID for an asynchronous test. 124 DWORD process_id() { return target_process_id_; } 125 126 private: 127 // Initializes the data in the object. Sets is_init_ to tree if the 128 // function succeeds. This is meant to be called from the constructor. 129 void Init(JobLevel job_level, TokenLevel startup_token, 130 TokenLevel main_token); 131 132 // The actual runner. 133 int InternalRunTest(const wchar_t* command); 134 135 BrokerServices* broker_; 136 TargetPolicy* policy_; 137 DWORD timeout_; 138 SboxTestsState state_; 139 bool is_init_; 140 bool is_async_; 141 bool no_sandbox_; 142 bool kill_on_destruction_; 143 base::win::ScopedHandle target_process_; 144 DWORD target_process_id_; 145 }; 146 147 // Returns the broker services. 148 BrokerServices* GetBroker(); 149 150 // Constructs a full path to a file inside the system32 (or syswow64) folder. 151 std::wstring MakePathToSys(const wchar_t* name, bool is_obj_man_path); 152 153 // Runs the given test on the target process. 154 int DispatchCall(int argc, wchar_t **argv); 155 156 } // namespace sandbox 157 158 #endif // SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_ 159