Home | History | Annotate | Download | only in common
      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