• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
IsSboxTestsResult(SboxTestResult result)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.
SetAsynchronous(bool is_async)103   void SetAsynchronous(bool is_async) { is_async_ = is_async; }
104 
105   // Sets TestRunner to return without waiting for the process to exit.
SetUnsandboxed(bool is_no_sandbox)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.
SetKillOnDestruction(bool value)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 
broker()119   BrokerServices* broker() { return broker_; }
120 
121   // Returns the process handle for an asynchronous test.
process()122   HANDLE process() { return target_process_.Get(); }
123 
124   // Returns the process ID for an asynchronous test.
process_id()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