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