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
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// 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/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 {
SBOX_TEST_FIRST_RESULT = CUSTOMER_CODE | SBOX_TESTS_FACILITY,
SBOX_TEST_SUCCEEDED,
SBOX_TEST_PING_OK,
SBOX_TEST_FIRST_INFO = SBOX_TEST_FIRST_RESULT | SEVERITY_INFO_FLAGS,
SBOX_TEST_DENIED, // Access was denied.
SBOX_TEST_NOT_FOUND, // The resource was not found.
SBOX_TEST_FIRST_ERROR = SBOX_TEST_FIRST_RESULT | SEVERITY_ERROR_FLAGS,
SBOX_TEST_SECOND_ERROR,
SBOX_TEST_THIRD_ERROR,
SBOX_TEST_FOURTH_ERROR,
SBOX_TEST_FIFTH_ERROR,
SBOX_TEST_SIXTH_ERROR,
SBOX_TEST_SEVENTH_ERROR,
SBOX_TEST_INVALID_PARAMETER,
SBOX_TEST_FAILED_TO_RUN_TEST,
SBOX_TEST_FAILED_TO_EXECUTE_COMMAND,
SBOX_TEST_TIMED_OUT,
SBOX_TEST_FAILED,
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 rule to the policy. The parameters are the same as the AddRule
// function in the sandbox.
bool AddRule(TargetPolicy::SubSystem subsystem,
TargetPolicy::Semantics semantics,
const wchar_t* pattern);
// 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(TargetPolicy::Semantics semantics, const wchar_t* pattern);
// Adds a filesystem rules to the policy. Returns true if the functions
// succeeds.
bool AddFsRule(TargetPolicy::Semantics 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);
// Sets TestRunner to return without waiting for the process to exit.
void SetAsynchronous(bool is_async) { is_async_ = is_async; }
// Sets TestRunner to return without waiting for the process to exit.
void SetUnsandboxed(bool is_no_sandbox) { no_sandbox_ = is_no_sandbox; }
// Sets the desired state for the test to run.
void SetTestState(SboxTestsState desired_state);
// 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_; }
// Returns the process ID for an asynchronous test.
DWORD process_id() { return target_process_id_; }
private:
// Initializes the data in the object. Sets is_init_ to tree if the
// function succeeds. This is meant to be called from the constructor.
void Init(JobLevel job_level, TokenLevel startup_token,
TokenLevel main_token);
// The actual runner.
int InternalRunTest(const wchar_t* command);
BrokerServices* broker_;
TargetPolicy* policy_;
DWORD timeout_;
SboxTestsState state_;
bool is_init_;
bool is_async_;
bool no_sandbox_;
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 (or syswow64) folder.
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_
|