1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_
#define SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_
#include <windows.h>
#include <string>
#include "base/dcheck_is_on.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "base/win/scoped_handle.h"
#include "sandbox/win/src/sandbox.h"
namespace sandbox {
// See winerror.h for details.
#define SEVERITY_INFO_FLAGS 0x40000000
#define SEVERITY_ERROR_FLAGS 0xC0000000
#define CUSTOMER_CODE 0x20000000
#define SBOX_TESTS_FACILITY 0x05B10000
// All the possible error codes returned by the child process in
// the sandbox.
enum SboxTestResult {
// First Result. (0x25B10000 or 632356864)
SBOX_TEST_FIRST_RESULT = CUSTOMER_CODE | SBOX_TESTS_FACILITY,
// Second result. (0x25B10001 or 632356865)
SBOX_TEST_SUCCEEDED,
// Ping OK. (0x25B10002 or 632356866)
SBOX_TEST_PING_OK,
// First info. (0x65B10000 or 1706098688)
SBOX_TEST_FIRST_INFO = SBOX_TEST_FIRST_RESULT | SEVERITY_INFO_FLAGS,
// Access was denied. (0x65B10001 or 1706098689)
SBOX_TEST_DENIED,
// The resource was not found. (0x65B10002 or 1706098690)
SBOX_TEST_NOT_FOUND,
// First error. (0xE5B10000 or -441384960)
SBOX_TEST_FIRST_ERROR = SBOX_TEST_FIRST_RESULT | SEVERITY_ERROR_FLAGS,
// Second error. (0xE5B10001 or -441384959)
SBOX_TEST_SECOND_ERROR,
// Third error. (0xE5B10002 or -441384958)
SBOX_TEST_THIRD_ERROR,
// Fourth error. (0xE5B10003 or -441384957)
SBOX_TEST_FOURTH_ERROR,
// Fifth error. (0xE5B10004 or -441384956)
SBOX_TEST_FIFTH_ERROR,
// Sixth error. (0xE5B10005 or -441384955)
SBOX_TEST_SIXTH_ERROR,
// Seventh error. (0xE5B10006 or -441384954)
SBOX_TEST_SEVENTH_ERROR,
// Invalid Parameter. (0xE5B10007 or -441384953)
SBOX_TEST_INVALID_PARAMETER,
// Failed to run test. (0xE5B10008 or -441384952)
SBOX_TEST_FAILED_TO_RUN_TEST,
// Failed to execute command. (0xE5B10009 or -441384951)
SBOX_TEST_FAILED_TO_EXECUTE_COMMAND,
// Test timed out. (0xE5B1000A or -441384950)
SBOX_TEST_TIMED_OUT,
// Test failed. (0xE5B1000B or -441384949)
SBOX_TEST_FAILED,
// Failed to configure sandbox before test. (0xE5B1000C or -441384948)
SBOX_TEST_FAILED_SETUP,
// Last Result. (0xE5B1000D or -441384947)
SBOX_TEST_LAST_RESULT
};
inline bool IsSboxTestsResult(SboxTestResult result) {
unsigned int code = static_cast<unsigned int>(result);
unsigned int first = static_cast<unsigned int>(SBOX_TEST_FIRST_RESULT);
unsigned int last = static_cast<unsigned int>(SBOX_TEST_LAST_RESULT);
return (code > first) && (code < last);
}
enum SboxTestsState {
MIN_STATE = 1,
BEFORE_INIT,
BEFORE_REVERT,
AFTER_REVERT,
EVERY_STATE,
MAX_STATE
};
#define SBOX_TESTS_API __declspec(dllexport)
#define SBOX_TESTS_COMMAND extern "C" SBOX_TESTS_API
extern "C" {
typedef int (*CommandFunction)(int argc, wchar_t **argv);
}
// Class to facilitate the launch of a test inside the sandbox.
class TestRunner {
public:
TestRunner(JobLevel job_level, TokenLevel startup_token,
TokenLevel main_token);
TestRunner();
~TestRunner();
// Adds a filesystem rules with the path of a file in system32. The function
// appends "pattern" to "system32" and then call AddRule. Return true if the
// function succeeds.
bool AddRuleSys32(FileSemantics semantics, const wchar_t* pattern);
// Adds a filesystem rules to the policy. Returns true if the functions
// succeeds.
bool AllowFileAccess(FileSemantics semantics, const wchar_t* pattern);
// Starts a child process in the sandbox and ask it to run |command|. Returns
// a SboxTestResult. By default, the test runs AFTER_REVERT.
int RunTest(const wchar_t* command);
// Sets the timeout value for the child to run the command and return.
void SetTimeout(DWORD timeout_ms);
void SetTimeout(base::TimeDelta timeout);
// Sets TestRunner to return without waiting for the process to exit.
void SetAsynchronous(bool is_async) { is_async_ = is_async; }
// Sets whether TestRunner sandboxes the child process. ("--no-sandbox")
void SetUnsandboxed(bool is_no_sandbox) { no_sandbox_ = is_no_sandbox; }
// Sets whether TestRunner should disable CSRSS or not (default true).
// Any test that needs to spawn a child process needs to set this to false.
void SetDisableCsrss(bool disable_csrss) { disable_csrss_ = disable_csrss; }
// Sets the desired state for the test to run.
void SetTestState(SboxTestsState desired_state);
// Sets a flag whether the process should be killed when the TestRunner is
// destroyed.
void SetKillOnDestruction(bool value) { kill_on_destruction_ = value; }
// Returns the pointers to the policy object. It can be used to modify
// the policy manually.
TargetPolicy* GetPolicy();
BrokerServices* broker() { return broker_; }
// Returns the process handle for an asynchronous test.
HANDLE process() { return target_process_.get(); }
// Returns the process ID for an asynchronous test.
DWORD process_id() { return target_process_id_; }
// Blocks until the number of tracked processes returns to zero.
bool WaitForAllTargets();
private:
// The actual runner.
int InternalRunTest(const wchar_t* command);
DWORD timeout_ms();
raw_ptr<BrokerServices> broker_;
std::unique_ptr<TargetPolicy> policy_;
base::TimeDelta timeout_;
SboxTestsState state_;
bool is_init_;
bool is_async_;
bool no_sandbox_;
bool disable_csrss_;
bool kill_on_destruction_;
base::win::ScopedHandle target_process_;
DWORD target_process_id_;
};
// Returns the broker services.
BrokerServices* GetBroker();
// Constructs a full path to a file inside the system32 folder.
std::wstring MakePathToSys32(const wchar_t* name, bool is_obj_man_path);
// Constructs a full path to a file inside the syswow64 folder.
std::wstring MakePathToSysWow64(const wchar_t* name, bool is_obj_man_path);
// Constructs a full path to a file inside the system32 (or syswow64) folder
// depending on whether process is running in wow64 or not.
std::wstring MakePathToSys(const wchar_t* name, bool is_obj_man_path);
// Runs the given test on the target process.
int DispatchCall(int argc, wchar_t **argv);
} // namespace sandbox
#endif // SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_
|