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 // Sandbox is a sandbox library for windows processes. Use when you want a
6 // 'privileged' process and a 'locked down process' to interact with.
7 // The privileged process is called the broker and it is started by external
8 // means (such as the user starting it). The 'sandboxed' process is called the
9 // target and it is started by the broker. There can be many target processes
10 // started by a single broker process. This library provides facilities
11 // for both the broker and the target.
12 //
13 // The design rationale and relevant documents can be found at http://go/sbox.
14 //
15 // Note: this header does not include the SandboxFactory definitions because
16 // there are cases where the Sandbox library is linked against the main .exe
17 // while its API needs to be used in a DLL.
18 
19 #ifndef SANDBOX_WIN_SRC_SANDBOX_H_
20 #define SANDBOX_WIN_SRC_SANDBOX_H_
21 
22 #if !defined(SANDBOX_FUZZ_TARGET)
23 #include <windows.h>
24 #else
25 #include "sandbox/win/fuzzer/fuzzer_types.h"
26 #endif
27 
28 #include <stddef.h>
29 #include <memory>
30 #include <vector>
31 
32 #include "base/memory/ref_counted.h"
33 #include "sandbox/win/src/sandbox_policy.h"
34 #include "sandbox/win/src/sandbox_types.h"
35 
36 // sandbox: Google User-Land Application Sandbox
37 namespace sandbox {
38 
39 class BrokerServices;
40 class PolicyDiagnosticsReceiver;
41 class ProcessState;
42 class TargetPolicy;
43 class TargetServices;
44 
45 // BrokerServices exposes all the broker API.
46 // The basic use is to start the target(s) and wait for them to end.
47 //
48 // This API is intended to be called in the following order
49 // (error checking omitted):
50 //  BrokerServices* broker = SandboxFactory::GetBrokerServices();
51 //  broker->Init();
52 //  PROCESS_INFORMATION target;
53 //  broker->SpawnTarget(target_exe_path, target_args, &target);
54 //  ::ResumeThread(target->hThread);
55 //  // -- later you can call:
56 //  broker->WaitForAllTargets(option);
57 //
58 class BrokerServices {
59  public:
60   // Initializes the broker. Must be called before any other on this class.
61   // returns ALL_OK if successful. All other return values imply failure.
62   // If the return is ERROR_GENERIC, you can call ::GetLastError() to get
63   // more information.
64   virtual ResultCode Init() = 0;
65 
66   // Returns the interface pointer to a new, empty policy object. Use this
67   // interface to specify the sandbox policy for new processes created by
68   // SpawnTarget()
69   virtual scoped_refptr<TargetPolicy> CreatePolicy() = 0;
70 
71   // Creates a new target (child process) in a suspended state.
72   // Parameters:
73   //   exe_path: This is the full path to the target binary. This parameter
74   //   can be null and in this case the exe path must be the first argument
75   //   of the command_line.
76   //   command_line: The arguments to be passed as command line to the new
77   //   process. This can be null if the exe_path parameter is not null.
78   //   policy: This is the pointer to the policy object for the sandbox to
79   //   be created.
80   //   last_warning: The argument will contain an indication on whether
81   //   the process security was initialized completely, Only set if the
82   //   process can be used without a serious compromise in security.
83   //   last_error: If an error or warning is returned from this method this
84   //   parameter will hold the last Win32 error value.
85   //   target: returns the resulting target process information such as process
86   //   handle and PID just as if CreateProcess() had been called. The caller is
87   //   responsible for closing the handles returned in this structure.
88   // Returns:
89   //   ALL_OK if successful. All other return values imply failure.
90   virtual ResultCode SpawnTarget(const wchar_t* exe_path,
91                                  const wchar_t* command_line,
92                                  base::EnvironmentMap& env_map,
93                                  scoped_refptr<TargetPolicy> policy,
94                                  ResultCode* last_warning,
95                                  DWORD* last_error,
96                                  PROCESS_INFORMATION* target) = 0;
97 
98   // This call blocks (waits) for all the targets to terminate.
99   // Returns:
100   //   ALL_OK if successful. All other return values imply failure.
101   //   If the return is ERROR_GENERIC, you can call ::GetLastError() to get
102   //   more information.
103   virtual ResultCode WaitForAllTargets() = 0;
104 
105   // Adds an unsandboxed process as a peer for policy decisions (e.g.
106   // HANDLES_DUP_ANY policy).
107   // Returns:
108   //   ALL_OK if successful. All other return values imply failure.
109   //   If the return is ERROR_GENERIC, you can call ::GetLastError() to get
110   //   more information.
111   virtual ResultCode AddTargetPeer(HANDLE peer_process) = 0;
112 
113   // This call creates a snapshot of policies managed by the sandbox and
114   // returns them via a helper class.
115   // Parameters:
116   //   receiver: The |PolicyDiagnosticsReceiver| implementation will be
117   //   called to accept the results of the call.
118   // Returns:
119   //   ALL_OK if the request was dispatched. All other return values
120   //   imply failure, and the responder will not receive its completion
121   //   callback.
122   virtual ResultCode GetPolicyDiagnostics(
123       std::unique_ptr<PolicyDiagnosticsReceiver> receiver) = 0;
124 
125  protected:
~BrokerServices()126   ~BrokerServices() {}
127 };
128 
129 // TargetServices models the current process from the perspective
130 // of a target process. To obtain a pointer to it use
131 // Sandbox::GetTargetServices(). Note that this call returns a non-null
132 // pointer only if this process is in fact a target. A process is a target
133 // only if the process was spawned by a call to BrokerServices::SpawnTarget().
134 //
135 // This API allows the target to gain access to resources with a high
136 // privilege token and then when it is ready to perform dangerous activities
137 // (such as download content from the web) it can lower its token and
138 // enter into locked-down (sandbox) mode.
139 // The typical usage is as follows:
140 //
141 //   TargetServices* target_services = Sandbox::GetTargetServices();
142 //   if (target_services) {
143 //     // We are the target.
144 //     target_services->Init();
145 //     // Do work that requires high privileges here.
146 //     // ....
147 //     // When ready to enter lock-down mode call LowerToken:
148 //     target_services->LowerToken();
149 //   }
150 //
151 // For more information see the BrokerServices API documentation.
152 class TargetServices {
153  public:
154   // Initializes the target. Must call this function before any other.
155   // returns ALL_OK if successful. All other return values imply failure.
156   // If the return is ERROR_GENERIC, you can call ::GetLastError() to get
157   // more information.
158   virtual ResultCode Init() = 0;
159 
160   // Discards the impersonation token and uses the lower token, call before
161   // processing any untrusted data or running third-party code. If this call
162   // fails the current process could be terminated immediately.
163   virtual void LowerToken() = 0;
164 
165   // Returns the ProcessState object. Through that object it's possible to have
166   // information about the current state of the process, such as whether
167   // LowerToken has been called or not.
168   virtual ProcessState* GetState() = 0;
169 
170   // Requests the broker to duplicate the supplied handle into the target
171   // process. The target process must be an active sandbox child process
172   // and the source process must have a corresponding policy allowing
173   // handle duplication for this object type.
174   // Returns:
175   //   ALL_OK if successful. All other return values imply failure.
176   //   If the return is ERROR_GENERIC, you can call ::GetLastError() to get
177   //   more information.
178   virtual ResultCode DuplicateHandle(HANDLE source_handle,
179                                      DWORD target_process_id,
180                                      HANDLE* target_handle,
181                                      DWORD desired_access,
182                                      DWORD options) = 0;
183 
184  protected:
~TargetServices()185   ~TargetServices() {}
186 };
187 
188 class PolicyInfo {
189  public:
190   // Returns a JSON representation of the policy snapshot.
191   // This pointer has the same lifetime as this PolicyInfo object.
192   virtual const char* JsonString() = 0;
~PolicyInfo()193   virtual ~PolicyInfo() {}
194 };
195 
196 // This is returned by BrokerServices::GetPolicyDiagnostics().
197 // PolicyInfo entries need not be ordered.
198 class PolicyList {
199  public:
200   virtual std::vector<std::unique_ptr<PolicyInfo>>::iterator begin() = 0;
201   virtual std::vector<std::unique_ptr<PolicyInfo>>::iterator end() = 0;
202   virtual size_t size() const = 0;
~PolicyList()203   virtual ~PolicyList() {}
204 };
205 
206 // This class mediates calls to BrokerServices::GetPolicyDiagnostics().
207 class PolicyDiagnosticsReceiver {
208  public:
209   // ReceiveDiagnostics() should return quickly and should not block the
210   // thread on which it is called.
211   virtual void ReceiveDiagnostics(std::unique_ptr<PolicyList> policies) = 0;
212   // OnError() is passed any errors encountered and |ReceiveDiagnostics|
213   // will not be called.
214   virtual void OnError(ResultCode code) = 0;
~PolicyDiagnosticsReceiver()215   virtual ~PolicyDiagnosticsReceiver() {}
216 };
217 
218 }  // namespace sandbox
219 
220 #endif  // SANDBOX_WIN_SRC_SANDBOX_H_
221