1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker
5*bb4ee6a4SAndroid Build Coastguard Worker #![cfg(windows)]
6*bb4ee6a4SAndroid Build Coastguard Worker
7*bb4ee6a4SAndroid Build Coastguard Worker use std::ffi::CStr;
8*bb4ee6a4SAndroid Build Coastguard Worker use std::fmt;
9*bb4ee6a4SAndroid Build Coastguard Worker use std::marker::PhantomData;
10*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::Once;
11*bb4ee6a4SAndroid Build Coastguard Worker
12*bb4ee6a4SAndroid Build Coastguard Worker use base::named_pipes;
13*bb4ee6a4SAndroid Build Coastguard Worker use base::AsRawDescriptor;
14*bb4ee6a4SAndroid Build Coastguard Worker use base::FromRawDescriptor;
15*bb4ee6a4SAndroid Build Coastguard Worker use base::SafeDescriptor;
16*bb4ee6a4SAndroid Build Coastguard Worker use win_util::win32_wide_string;
17*bb4ee6a4SAndroid Build Coastguard Worker
18*bb4ee6a4SAndroid Build Coastguard Worker #[cfg_attr(windows, path = "../bindings.rs")]
19*bb4ee6a4SAndroid Build Coastguard Worker #[allow(non_camel_case_types)]
20*bb4ee6a4SAndroid Build Coastguard Worker #[allow(non_snake_case)]
21*bb4ee6a4SAndroid Build Coastguard Worker #[allow(non_upper_case_globals)]
22*bb4ee6a4SAndroid Build Coastguard Worker #[allow(deref_nullptr)]
23*bb4ee6a4SAndroid Build Coastguard Worker pub mod bindings;
24*bb4ee6a4SAndroid Build Coastguard Worker
25*bb4ee6a4SAndroid Build Coastguard Worker pub mod policy;
26*bb4ee6a4SAndroid Build Coastguard Worker
27*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::IntegrityLevel;
28*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::JobLevel;
29*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MitigationFlags;
30*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::ResultCode;
31*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::Semantics;
32*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::SubSystem;
33*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::TokenLevel;
34*bb4ee6a4SAndroid Build Coastguard Worker use bindings::DWORD;
35*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::JOB_OBJECT_UILIMIT_ALL;
36*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::JOB_OBJECT_UILIMIT_DESKTOP;
37*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::JOB_OBJECT_UILIMIT_DISPLAYSETTINGS;
38*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::JOB_OBJECT_UILIMIT_EXITWINDOWS;
39*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::JOB_OBJECT_UILIMIT_GLOBALATOMS;
40*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::JOB_OBJECT_UILIMIT_HANDLES;
41*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::JOB_OBJECT_UILIMIT_NONE;
42*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::JOB_OBJECT_UILIMIT_READCLIPBOARD;
43*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS;
44*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
45*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_BOTTOM_UP_ASLR;
46*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_CET_DISABLED;
47*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_DEP;
48*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_DEP_NO_ATL_THUNK;
49*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_DLL_SEARCH_ORDER;
50*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_DYNAMIC_CODE_DISABLE;
51*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT;
52*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_DYNAMIC_CODE_OPT_OUT_THIS_THREAD;
53*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_EXTENSION_POINT_DISABLE;
54*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_FORCE_MS_SIGNED_BINS;
55*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_HARDEN_TOKEN_IL_POLICY;
56*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_HEAP_TERMINATE;
57*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_HIGH_ENTROPY_ASLR;
58*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_IMAGE_LOAD_NO_LOW_LABEL;
59*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_IMAGE_LOAD_NO_REMOTE;
60*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_IMAGE_LOAD_PREFER_SYS32;
61*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_KTM_COMPONENT;
62*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_NONSYSTEM_FONT_DISABLE;
63*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_RELOCATE_IMAGE;
64*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_RELOCATE_IMAGE_REQUIRED;
65*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION;
66*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_SEHOP;
67*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_STRICT_HANDLE_CHECKS;
68*bb4ee6a4SAndroid Build Coastguard Worker pub use bindings::MITIGATION_WIN32K_DISABLE;
69*bb4ee6a4SAndroid Build Coastguard Worker use bindings::PROCESS_INFORMATION;
70*bb4ee6a4SAndroid Build Coastguard Worker
71*bb4ee6a4SAndroid Build Coastguard Worker type Result<T> = std::result::Result<T, SandboxError>;
72*bb4ee6a4SAndroid Build Coastguard Worker
73*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, Copy, Clone)]
74*bb4ee6a4SAndroid Build Coastguard Worker pub struct SandboxError {
75*bb4ee6a4SAndroid Build Coastguard Worker result_code: ResultCode,
76*bb4ee6a4SAndroid Build Coastguard Worker error_code: Option<u32>,
77*bb4ee6a4SAndroid Build Coastguard Worker }
78*bb4ee6a4SAndroid Build Coastguard Worker
79*bb4ee6a4SAndroid Build Coastguard Worker impl fmt::Display for SandboxError {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result80*bb4ee6a4SAndroid Build Coastguard Worker fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81*bb4ee6a4SAndroid Build Coastguard Worker match self.error_code {
82*bb4ee6a4SAndroid Build Coastguard Worker Some(error_code) => write!(
83*bb4ee6a4SAndroid Build Coastguard Worker f,
84*bb4ee6a4SAndroid Build Coastguard Worker "Sandbox error code: {:?}, win32 error code: {}",
85*bb4ee6a4SAndroid Build Coastguard Worker self.result_code, error_code,
86*bb4ee6a4SAndroid Build Coastguard Worker ),
87*bb4ee6a4SAndroid Build Coastguard Worker None => write!(f, "Sandbox error code: {:?}", self.result_code),
88*bb4ee6a4SAndroid Build Coastguard Worker }
89*bb4ee6a4SAndroid Build Coastguard Worker }
90*bb4ee6a4SAndroid Build Coastguard Worker }
91*bb4ee6a4SAndroid Build Coastguard Worker
92*bb4ee6a4SAndroid Build Coastguard Worker impl std::error::Error for SandboxError {
description(&self) -> &str93*bb4ee6a4SAndroid Build Coastguard Worker fn description(&self) -> &str {
94*bb4ee6a4SAndroid Build Coastguard Worker "sandbox error"
95*bb4ee6a4SAndroid Build Coastguard Worker }
96*bb4ee6a4SAndroid Build Coastguard Worker }
97*bb4ee6a4SAndroid Build Coastguard Worker
98*bb4ee6a4SAndroid Build Coastguard Worker impl SandboxError {
new(result_code: ResultCode) -> SandboxError99*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(result_code: ResultCode) -> SandboxError {
100*bb4ee6a4SAndroid Build Coastguard Worker if result_code == bindings::ResultCode::SBOX_ERROR_GENERIC {
101*bb4ee6a4SAndroid Build Coastguard Worker return SandboxError::from(std::io::Error::last_os_error());
102*bb4ee6a4SAndroid Build Coastguard Worker }
103*bb4ee6a4SAndroid Build Coastguard Worker SandboxError {
104*bb4ee6a4SAndroid Build Coastguard Worker result_code,
105*bb4ee6a4SAndroid Build Coastguard Worker error_code: None,
106*bb4ee6a4SAndroid Build Coastguard Worker }
107*bb4ee6a4SAndroid Build Coastguard Worker }
108*bb4ee6a4SAndroid Build Coastguard Worker }
109*bb4ee6a4SAndroid Build Coastguard Worker
110*bb4ee6a4SAndroid Build Coastguard Worker impl From<std::io::Error> for SandboxError {
from(error: std::io::Error) -> Self111*bb4ee6a4SAndroid Build Coastguard Worker fn from(error: std::io::Error) -> Self {
112*bb4ee6a4SAndroid Build Coastguard Worker let error_code = error.raw_os_error().map(|e| e as u32);
113*bb4ee6a4SAndroid Build Coastguard Worker SandboxError {
114*bb4ee6a4SAndroid Build Coastguard Worker result_code: bindings::ResultCode::SBOX_ERROR_GENERIC,
115*bb4ee6a4SAndroid Build Coastguard Worker error_code,
116*bb4ee6a4SAndroid Build Coastguard Worker }
117*bb4ee6a4SAndroid Build Coastguard Worker }
118*bb4ee6a4SAndroid Build Coastguard Worker }
119*bb4ee6a4SAndroid Build Coastguard Worker
120*bb4ee6a4SAndroid Build Coastguard Worker pub type SandboxWarning = SandboxError;
121*bb4ee6a4SAndroid Build Coastguard Worker
122*bb4ee6a4SAndroid Build Coastguard Worker /// Encapsulates broker-related functionality for the sandbox.
123*bb4ee6a4SAndroid Build Coastguard Worker ///
124*bb4ee6a4SAndroid Build Coastguard Worker /// This struct and its methods are not thread safe, in general. Only a single
125*bb4ee6a4SAndroid Build Coastguard Worker /// thread should call the methods on this struct.
126*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, PartialEq, Clone)]
127*bb4ee6a4SAndroid Build Coastguard Worker pub struct BrokerServices {
128*bb4ee6a4SAndroid Build Coastguard Worker broker: *mut bindings::BrokerServices,
129*bb4ee6a4SAndroid Build Coastguard Worker }
130*bb4ee6a4SAndroid Build Coastguard Worker
131*bb4ee6a4SAndroid Build Coastguard Worker /// Encapsulates target-related functionality for the sandbox.
132*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, PartialEq, Clone)]
133*bb4ee6a4SAndroid Build Coastguard Worker pub struct TargetServices {
134*bb4ee6a4SAndroid Build Coastguard Worker target: *mut bindings::TargetServices,
135*bb4ee6a4SAndroid Build Coastguard Worker }
136*bb4ee6a4SAndroid Build Coastguard Worker
137*bb4ee6a4SAndroid Build Coastguard Worker /// Defines sandbox policies for target processes.
138*bb4ee6a4SAndroid Build Coastguard Worker pub struct TargetPolicy<'a> {
139*bb4ee6a4SAndroid Build Coastguard Worker policy: TargetPolicyWrapper,
140*bb4ee6a4SAndroid Build Coastguard Worker _marker: PhantomData<&'a dyn AsRawDescriptor>,
141*bb4ee6a4SAndroid Build Coastguard Worker }
142*bb4ee6a4SAndroid Build Coastguard Worker
143*bb4ee6a4SAndroid Build Coastguard Worker struct TargetPolicyWrapper(*mut bindings::TargetPolicy);
144*bb4ee6a4SAndroid Build Coastguard Worker
145*bb4ee6a4SAndroid Build Coastguard Worker impl Drop for TargetPolicyWrapper {
drop(&mut self)146*bb4ee6a4SAndroid Build Coastguard Worker fn drop(&mut self) {
147*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicyWrapper can only be constructed with a non-null pointer.
148*bb4ee6a4SAndroid Build Coastguard Worker unsafe { bindings::sbox_release_policy(self.0) };
149*bb4ee6a4SAndroid Build Coastguard Worker }
150*bb4ee6a4SAndroid Build Coastguard Worker }
151*bb4ee6a4SAndroid Build Coastguard Worker
152*bb4ee6a4SAndroid Build Coastguard Worker pub struct ProcessInformation {
153*bb4ee6a4SAndroid Build Coastguard Worker pub process: SafeDescriptor,
154*bb4ee6a4SAndroid Build Coastguard Worker pub thread: SafeDescriptor,
155*bb4ee6a4SAndroid Build Coastguard Worker pub process_id: u32,
156*bb4ee6a4SAndroid Build Coastguard Worker pub thread_id: u32,
157*bb4ee6a4SAndroid Build Coastguard Worker }
158*bb4ee6a4SAndroid Build Coastguard Worker
159*bb4ee6a4SAndroid Build Coastguard Worker pub struct PolicyInfo {
160*bb4ee6a4SAndroid Build Coastguard Worker policy_info: *mut bindings::PolicyInfo,
161*bb4ee6a4SAndroid Build Coastguard Worker }
162*bb4ee6a4SAndroid Build Coastguard Worker
163*bb4ee6a4SAndroid Build Coastguard Worker impl Drop for PolicyInfo {
drop(&mut self)164*bb4ee6a4SAndroid Build Coastguard Worker fn drop(&mut self) {
165*bb4ee6a4SAndroid Build Coastguard Worker unsafe { bindings::sbox_release_policy_info(self.policy_info) }
166*bb4ee6a4SAndroid Build Coastguard Worker }
167*bb4ee6a4SAndroid Build Coastguard Worker }
168*bb4ee6a4SAndroid Build Coastguard Worker
169*bb4ee6a4SAndroid Build Coastguard Worker /// Returns true if this process is the broker process.
is_sandbox_broker() -> bool170*bb4ee6a4SAndroid Build Coastguard Worker pub fn is_sandbox_broker() -> bool {
171*bb4ee6a4SAndroid Build Coastguard Worker // Safe because the returned raw pointer is a non-owning pointer and we are free
172*bb4ee6a4SAndroid Build Coastguard Worker // to let it drop unmanaged.
173*bb4ee6a4SAndroid Build Coastguard Worker unsafe { !bindings::get_broker_services().is_null() }
174*bb4ee6a4SAndroid Build Coastguard Worker }
175*bb4ee6a4SAndroid Build Coastguard Worker
176*bb4ee6a4SAndroid Build Coastguard Worker /// Returns true if this process is a target process.
is_sandbox_target() -> bool177*bb4ee6a4SAndroid Build Coastguard Worker pub fn is_sandbox_target() -> bool {
178*bb4ee6a4SAndroid Build Coastguard Worker // Safe because the returned raw pointer is a non-owning pointer and we are
179*bb4ee6a4SAndroid Build Coastguard Worker // free to let it drop unmanaged.
180*bb4ee6a4SAndroid Build Coastguard Worker unsafe { !bindings::get_target_services().is_null() }
181*bb4ee6a4SAndroid Build Coastguard Worker }
182*bb4ee6a4SAndroid Build Coastguard Worker
183*bb4ee6a4SAndroid Build Coastguard Worker impl BrokerServices {
184*bb4ee6a4SAndroid Build Coastguard Worker /// Returns an initialized broker API interface if the process is the broker.
get() -> Result<Option<BrokerServices>>185*bb4ee6a4SAndroid Build Coastguard Worker pub fn get() -> Result<Option<BrokerServices>> {
186*bb4ee6a4SAndroid Build Coastguard Worker static INIT: Once = Once::new();
187*bb4ee6a4SAndroid Build Coastguard Worker static mut RESULT: Result<()> = Ok(());
188*bb4ee6a4SAndroid Build Coastguard Worker static mut BROKER: Option<BrokerServices> = None;
189*bb4ee6a4SAndroid Build Coastguard Worker
190*bb4ee6a4SAndroid Build Coastguard Worker // Initialize broker services. Should be called once before use.
191*bb4ee6a4SAndroid Build Coastguard Worker // Safe because RESULT is only written once, and call_once will cause
192*bb4ee6a4SAndroid Build Coastguard Worker // other readers to block until execution of the block is complete.
193*bb4ee6a4SAndroid Build Coastguard Worker // Also checks for and eliminates any null pointers.
194*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
195*bb4ee6a4SAndroid Build Coastguard Worker INIT.call_once(|| {
196*bb4ee6a4SAndroid Build Coastguard Worker let broker = bindings::get_broker_services();
197*bb4ee6a4SAndroid Build Coastguard Worker if broker.is_null() {
198*bb4ee6a4SAndroid Build Coastguard Worker return;
199*bb4ee6a4SAndroid Build Coastguard Worker }
200*bb4ee6a4SAndroid Build Coastguard Worker BROKER = Some(BrokerServices { broker });
201*bb4ee6a4SAndroid Build Coastguard Worker RESULT = BROKER.as_mut().unwrap().init();
202*bb4ee6a4SAndroid Build Coastguard Worker });
203*bb4ee6a4SAndroid Build Coastguard Worker if BROKER.is_none() {
204*bb4ee6a4SAndroid Build Coastguard Worker return Ok(None);
205*bb4ee6a4SAndroid Build Coastguard Worker }
206*bb4ee6a4SAndroid Build Coastguard Worker match RESULT {
207*bb4ee6a4SAndroid Build Coastguard Worker Err(e) => Err(e),
208*bb4ee6a4SAndroid Build Coastguard Worker Ok(_) => Ok(Some(BROKER.as_mut().unwrap().clone())),
209*bb4ee6a4SAndroid Build Coastguard Worker }
210*bb4ee6a4SAndroid Build Coastguard Worker }
211*bb4ee6a4SAndroid Build Coastguard Worker }
212*bb4ee6a4SAndroid Build Coastguard Worker
213*bb4ee6a4SAndroid Build Coastguard Worker /// Initializes the broker. Must be called once before calling any other
214*bb4ee6a4SAndroid Build Coastguard Worker /// methods.
215*bb4ee6a4SAndroid Build Coastguard Worker ///
216*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a &mut self because sbox_broker_init mutates the underlying broker
217*bb4ee6a4SAndroid Build Coastguard Worker /// object.
init(&mut self) -> Result<()>218*bb4ee6a4SAndroid Build Coastguard Worker fn init(&mut self) -> Result<()> {
219*bb4ee6a4SAndroid Build Coastguard Worker // Safe because BrokerServices can only be constructed with a non-null
220*bb4ee6a4SAndroid Build Coastguard Worker // pointer.
221*bb4ee6a4SAndroid Build Coastguard Worker let result_code = unsafe { bindings::sbox_broker_init(self.broker) };
222*bb4ee6a4SAndroid Build Coastguard Worker if result_code != ResultCode::SBOX_ALL_OK {
223*bb4ee6a4SAndroid Build Coastguard Worker Err(SandboxError::new(result_code))
224*bb4ee6a4SAndroid Build Coastguard Worker } else {
225*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
226*bb4ee6a4SAndroid Build Coastguard Worker }
227*bb4ee6a4SAndroid Build Coastguard Worker }
228*bb4ee6a4SAndroid Build Coastguard Worker
229*bb4ee6a4SAndroid Build Coastguard Worker /// Create a new policy object.
create_policy<'a>(&self) -> TargetPolicy<'a>230*bb4ee6a4SAndroid Build Coastguard Worker pub fn create_policy<'a>(&self) -> TargetPolicy<'a> {
231*bb4ee6a4SAndroid Build Coastguard Worker // Safe because BrokerServices can only be constructed with a non-null pointer.
232*bb4ee6a4SAndroid Build Coastguard Worker let policy = unsafe { bindings::sbox_create_policy(self.broker) };
233*bb4ee6a4SAndroid Build Coastguard Worker TargetPolicy {
234*bb4ee6a4SAndroid Build Coastguard Worker policy: TargetPolicyWrapper(policy),
235*bb4ee6a4SAndroid Build Coastguard Worker _marker: PhantomData,
236*bb4ee6a4SAndroid Build Coastguard Worker }
237*bb4ee6a4SAndroid Build Coastguard Worker }
238*bb4ee6a4SAndroid Build Coastguard Worker
239*bb4ee6a4SAndroid Build Coastguard Worker /// Spawn a new target process. This process is created with the main thread
240*bb4ee6a4SAndroid Build Coastguard Worker /// in a suspended state.
241*bb4ee6a4SAndroid Build Coastguard Worker ///
242*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_spawn_target()` mutates the underlying
243*bb4ee6a4SAndroid Build Coastguard Worker /// broker object.
spawn_target( &mut self, exe_path: &str, command_line: &str, policy: &TargetPolicy, ) -> Result<(ProcessInformation, Option<SandboxWarning>)>244*bb4ee6a4SAndroid Build Coastguard Worker pub fn spawn_target(
245*bb4ee6a4SAndroid Build Coastguard Worker &mut self,
246*bb4ee6a4SAndroid Build Coastguard Worker exe_path: &str,
247*bb4ee6a4SAndroid Build Coastguard Worker command_line: &str,
248*bb4ee6a4SAndroid Build Coastguard Worker policy: &TargetPolicy,
249*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<(ProcessInformation, Option<SandboxWarning>)> {
250*bb4ee6a4SAndroid Build Coastguard Worker let mut last_warning = ResultCode::SBOX_ALL_OK;
251*bb4ee6a4SAndroid Build Coastguard Worker let mut last_error: DWORD = 0;
252*bb4ee6a4SAndroid Build Coastguard Worker let mut target = PROCESS_INFORMATION {
253*bb4ee6a4SAndroid Build Coastguard Worker dwProcessId: 0,
254*bb4ee6a4SAndroid Build Coastguard Worker dwThreadId: 0,
255*bb4ee6a4SAndroid Build Coastguard Worker hThread: std::ptr::null_mut(),
256*bb4ee6a4SAndroid Build Coastguard Worker hProcess: std::ptr::null_mut(),
257*bb4ee6a4SAndroid Build Coastguard Worker };
258*bb4ee6a4SAndroid Build Coastguard Worker // Safe because the external arguments must be constructed in a safe
259*bb4ee6a4SAndroid Build Coastguard Worker // way, and the rest of the arguments are pointers to valid objects
260*bb4ee6a4SAndroid Build Coastguard Worker // created in this function.
261*bb4ee6a4SAndroid Build Coastguard Worker let result = unsafe {
262*bb4ee6a4SAndroid Build Coastguard Worker bindings::sbox_spawn_target(
263*bb4ee6a4SAndroid Build Coastguard Worker self.broker,
264*bb4ee6a4SAndroid Build Coastguard Worker win32_wide_string(exe_path).as_ptr(),
265*bb4ee6a4SAndroid Build Coastguard Worker win32_wide_string(command_line).as_ptr(),
266*bb4ee6a4SAndroid Build Coastguard Worker policy.policy.0,
267*bb4ee6a4SAndroid Build Coastguard Worker &mut last_warning,
268*bb4ee6a4SAndroid Build Coastguard Worker &mut last_error,
269*bb4ee6a4SAndroid Build Coastguard Worker &mut target,
270*bb4ee6a4SAndroid Build Coastguard Worker )
271*bb4ee6a4SAndroid Build Coastguard Worker };
272*bb4ee6a4SAndroid Build Coastguard Worker if result != ResultCode::SBOX_ALL_OK {
273*bb4ee6a4SAndroid Build Coastguard Worker return Err(SandboxError {
274*bb4ee6a4SAndroid Build Coastguard Worker result_code: result,
275*bb4ee6a4SAndroid Build Coastguard Worker error_code: Some(last_error),
276*bb4ee6a4SAndroid Build Coastguard Worker });
277*bb4ee6a4SAndroid Build Coastguard Worker }
278*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we are adopting the process and thread handles here,
279*bb4ee6a4SAndroid Build Coastguard Worker // and they won't be used outside of the SafeDescriptor after this
280*bb4ee6a4SAndroid Build Coastguard Worker // function returns.
281*bb4ee6a4SAndroid Build Coastguard Worker let process = unsafe {
282*bb4ee6a4SAndroid Build Coastguard Worker ProcessInformation {
283*bb4ee6a4SAndroid Build Coastguard Worker process: SafeDescriptor::from_raw_descriptor(target.hProcess),
284*bb4ee6a4SAndroid Build Coastguard Worker thread: SafeDescriptor::from_raw_descriptor(target.hThread),
285*bb4ee6a4SAndroid Build Coastguard Worker process_id: target.dwProcessId,
286*bb4ee6a4SAndroid Build Coastguard Worker thread_id: target.dwThreadId,
287*bb4ee6a4SAndroid Build Coastguard Worker }
288*bb4ee6a4SAndroid Build Coastguard Worker };
289*bb4ee6a4SAndroid Build Coastguard Worker if last_warning != ResultCode::SBOX_ALL_OK {
290*bb4ee6a4SAndroid Build Coastguard Worker Ok((
291*bb4ee6a4SAndroid Build Coastguard Worker process,
292*bb4ee6a4SAndroid Build Coastguard Worker Some(SandboxWarning {
293*bb4ee6a4SAndroid Build Coastguard Worker result_code: last_warning,
294*bb4ee6a4SAndroid Build Coastguard Worker error_code: Some(last_error),
295*bb4ee6a4SAndroid Build Coastguard Worker }),
296*bb4ee6a4SAndroid Build Coastguard Worker ))
297*bb4ee6a4SAndroid Build Coastguard Worker } else {
298*bb4ee6a4SAndroid Build Coastguard Worker Ok((process, None))
299*bb4ee6a4SAndroid Build Coastguard Worker }
300*bb4ee6a4SAndroid Build Coastguard Worker }
301*bb4ee6a4SAndroid Build Coastguard Worker
302*bb4ee6a4SAndroid Build Coastguard Worker /// Waits (blocks) for all target processes to exit.
303*bb4ee6a4SAndroid Build Coastguard Worker ///
304*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_wait_for_all_targets()` mutates the
305*bb4ee6a4SAndroid Build Coastguard Worker /// underlying broker object.
wait_for_all_targets(&mut self) -> Result<()>306*bb4ee6a4SAndroid Build Coastguard Worker pub fn wait_for_all_targets(&mut self) -> Result<()> {
307*bb4ee6a4SAndroid Build Coastguard Worker // Safe because BrokerServices can only be constructed with a non-null pointer.
308*bb4ee6a4SAndroid Build Coastguard Worker let result_code = unsafe { bindings::sbox_wait_for_all_targets(self.broker) };
309*bb4ee6a4SAndroid Build Coastguard Worker if result_code != ResultCode::SBOX_ALL_OK {
310*bb4ee6a4SAndroid Build Coastguard Worker Err(SandboxError::new(result_code))
311*bb4ee6a4SAndroid Build Coastguard Worker } else {
312*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
313*bb4ee6a4SAndroid Build Coastguard Worker }
314*bb4ee6a4SAndroid Build Coastguard Worker }
315*bb4ee6a4SAndroid Build Coastguard Worker }
316*bb4ee6a4SAndroid Build Coastguard Worker
317*bb4ee6a4SAndroid Build Coastguard Worker impl TargetServices {
318*bb4ee6a4SAndroid Build Coastguard Worker /// Returns an initialized target API interface if the process is the target.
get() -> Result<Option<TargetServices>>319*bb4ee6a4SAndroid Build Coastguard Worker pub fn get() -> Result<Option<TargetServices>> {
320*bb4ee6a4SAndroid Build Coastguard Worker static INIT: Once = Once::new();
321*bb4ee6a4SAndroid Build Coastguard Worker static mut RESULT: Result<()> = Ok(());
322*bb4ee6a4SAndroid Build Coastguard Worker static mut TARGET: Option<TargetServices> = None;
323*bb4ee6a4SAndroid Build Coastguard Worker
324*bb4ee6a4SAndroid Build Coastguard Worker // Initialize target services. Should be called once before use.
325*bb4ee6a4SAndroid Build Coastguard Worker // Safe because RESULT is only written once, and call_once will cause
326*bb4ee6a4SAndroid Build Coastguard Worker // other readers to block until execution of the block is complete.
327*bb4ee6a4SAndroid Build Coastguard Worker // Also checks for and eliminates any null pointers.
328*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
329*bb4ee6a4SAndroid Build Coastguard Worker INIT.call_once(|| {
330*bb4ee6a4SAndroid Build Coastguard Worker let target = bindings::get_target_services();
331*bb4ee6a4SAndroid Build Coastguard Worker if target.is_null() {
332*bb4ee6a4SAndroid Build Coastguard Worker return;
333*bb4ee6a4SAndroid Build Coastguard Worker }
334*bb4ee6a4SAndroid Build Coastguard Worker TARGET = Some(TargetServices { target });
335*bb4ee6a4SAndroid Build Coastguard Worker RESULT = TARGET.as_mut().unwrap().init()
336*bb4ee6a4SAndroid Build Coastguard Worker });
337*bb4ee6a4SAndroid Build Coastguard Worker if TARGET.is_none() {
338*bb4ee6a4SAndroid Build Coastguard Worker return Ok(None);
339*bb4ee6a4SAndroid Build Coastguard Worker }
340*bb4ee6a4SAndroid Build Coastguard Worker // Initialize target services. If TargetServices is already initialized,
341*bb4ee6a4SAndroid Build Coastguard Worker // this is a no-op.
342*bb4ee6a4SAndroid Build Coastguard Worker match RESULT {
343*bb4ee6a4SAndroid Build Coastguard Worker Err(e) => Err(e),
344*bb4ee6a4SAndroid Build Coastguard Worker Ok(_) => Ok(Some(TARGET.as_mut().unwrap().clone())),
345*bb4ee6a4SAndroid Build Coastguard Worker }
346*bb4ee6a4SAndroid Build Coastguard Worker }
347*bb4ee6a4SAndroid Build Coastguard Worker }
348*bb4ee6a4SAndroid Build Coastguard Worker
349*bb4ee6a4SAndroid Build Coastguard Worker /// Initializes the target. Must be called once before calling any other
350*bb4ee6a4SAndroid Build Coastguard Worker /// methods.
351*bb4ee6a4SAndroid Build Coastguard Worker ///
352*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_target_init()` mutates the underlying
353*bb4ee6a4SAndroid Build Coastguard Worker /// target object.
init(&mut self) -> Result<()>354*bb4ee6a4SAndroid Build Coastguard Worker fn init(&mut self) -> Result<()> {
355*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetServices can only be constructed with a non-null pointer.
356*bb4ee6a4SAndroid Build Coastguard Worker let result_code = unsafe { bindings::sbox_target_init(self.target) };
357*bb4ee6a4SAndroid Build Coastguard Worker if result_code != ResultCode::SBOX_ALL_OK {
358*bb4ee6a4SAndroid Build Coastguard Worker Err(SandboxError::new(result_code))
359*bb4ee6a4SAndroid Build Coastguard Worker } else {
360*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
361*bb4ee6a4SAndroid Build Coastguard Worker }
362*bb4ee6a4SAndroid Build Coastguard Worker }
363*bb4ee6a4SAndroid Build Coastguard Worker
364*bb4ee6a4SAndroid Build Coastguard Worker /// Discards the targets impersonation token and uses the lower token.
365*bb4ee6a4SAndroid Build Coastguard Worker ///
366*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_lower_token()` mutates the underlying
367*bb4ee6a4SAndroid Build Coastguard Worker /// target object.
lower_token(&mut self)368*bb4ee6a4SAndroid Build Coastguard Worker pub fn lower_token(&mut self) {
369*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetServices can only be constructed with a non-null pointer.
370*bb4ee6a4SAndroid Build Coastguard Worker unsafe { bindings::sbox_lower_token(self.target) };
371*bb4ee6a4SAndroid Build Coastguard Worker }
372*bb4ee6a4SAndroid Build Coastguard Worker }
373*bb4ee6a4SAndroid Build Coastguard Worker
374*bb4ee6a4SAndroid Build Coastguard Worker impl<'a> TargetPolicy<'a> {
375*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the security level for the process' two tokens.
376*bb4ee6a4SAndroid Build Coastguard Worker ///
377*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_set_token_level()` mutates the
378*bb4ee6a4SAndroid Build Coastguard Worker /// underlying policy object.
set_token_level(&mut self, initial: TokenLevel, lockdown: TokenLevel) -> Result<()>379*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_token_level(&mut self, initial: TokenLevel, lockdown: TokenLevel) -> Result<()> {
380*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
381*bb4ee6a4SAndroid Build Coastguard Worker match unsafe { bindings::sbox_set_token_level(self.policy.0, initial, lockdown) } {
382*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => Ok(()),
383*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
384*bb4ee6a4SAndroid Build Coastguard Worker }
385*bb4ee6a4SAndroid Build Coastguard Worker }
386*bb4ee6a4SAndroid Build Coastguard Worker
387*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the initial token level.
initial_token_level(&self) -> TokenLevel388*bb4ee6a4SAndroid Build Coastguard Worker pub fn initial_token_level(&self) -> TokenLevel {
389*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
390*bb4ee6a4SAndroid Build Coastguard Worker unsafe { bindings::sbox_get_initial_token_level(self.policy.0) }
391*bb4ee6a4SAndroid Build Coastguard Worker }
392*bb4ee6a4SAndroid Build Coastguard Worker
393*bb4ee6a4SAndroid Build Coastguard Worker /// Gets the lockdown token level.
lockdown_token_level(&self) -> TokenLevel394*bb4ee6a4SAndroid Build Coastguard Worker pub fn lockdown_token_level(&self) -> TokenLevel {
395*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
396*bb4ee6a4SAndroid Build Coastguard Worker unsafe { bindings::sbox_get_lockdown_token_level(self.policy.0) }
397*bb4ee6a4SAndroid Build Coastguard Worker }
398*bb4ee6a4SAndroid Build Coastguard Worker
399*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the security level of the job object to which the process will
400*bb4ee6a4SAndroid Build Coastguard Worker /// belong.
401*bb4ee6a4SAndroid Build Coastguard Worker ///
402*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_set_job_level()` mutates the
403*bb4ee6a4SAndroid Build Coastguard Worker /// underlying policy object.
set_job_level(&mut self, job_level: JobLevel, ui_exceptions: u32) -> Result<()>404*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_job_level(&mut self, job_level: JobLevel, ui_exceptions: u32) -> Result<()> {
405*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
406*bb4ee6a4SAndroid Build Coastguard Worker match unsafe { bindings::sbox_set_job_level(self.policy.0, job_level, ui_exceptions) } {
407*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => Ok(()),
408*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
409*bb4ee6a4SAndroid Build Coastguard Worker }
410*bb4ee6a4SAndroid Build Coastguard Worker }
411*bb4ee6a4SAndroid Build Coastguard Worker
412*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the job level.
job_level(&self) -> JobLevel413*bb4ee6a4SAndroid Build Coastguard Worker pub fn job_level(&self) -> JobLevel {
414*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
415*bb4ee6a4SAndroid Build Coastguard Worker unsafe { bindings::sbox_get_job_level(self.policy.0) }
416*bb4ee6a4SAndroid Build Coastguard Worker }
417*bb4ee6a4SAndroid Build Coastguard Worker
418*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the initial integrity level of the process in the sandbox.
419*bb4ee6a4SAndroid Build Coastguard Worker ///
420*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_set_integrity_level()` mutates the
421*bb4ee6a4SAndroid Build Coastguard Worker /// underlying policy object.
set_integrity_level(&mut self, level: IntegrityLevel) -> Result<()>422*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_integrity_level(&mut self, level: IntegrityLevel) -> Result<()> {
423*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
424*bb4ee6a4SAndroid Build Coastguard Worker match unsafe { bindings::sbox_set_integrity_level(self.policy.0, level) } {
425*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => Ok(()),
426*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
427*bb4ee6a4SAndroid Build Coastguard Worker }
428*bb4ee6a4SAndroid Build Coastguard Worker }
429*bb4ee6a4SAndroid Build Coastguard Worker
430*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the delayed integrity level of the process in the sandbox.
431*bb4ee6a4SAndroid Build Coastguard Worker ///
432*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_set_delayed_integrity_level()` mutates the
433*bb4ee6a4SAndroid Build Coastguard Worker /// underlying policy object.
set_delayed_integrity_level(&mut self, level: IntegrityLevel) -> Result<()>434*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_delayed_integrity_level(&mut self, level: IntegrityLevel) -> Result<()> {
435*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
436*bb4ee6a4SAndroid Build Coastguard Worker match unsafe { bindings::sbox_set_delayed_integrity_level(self.policy.0, level) } {
437*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => Ok(()),
438*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
439*bb4ee6a4SAndroid Build Coastguard Worker }
440*bb4ee6a4SAndroid Build Coastguard Worker }
441*bb4ee6a4SAndroid Build Coastguard Worker
442*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the initial integrity level used.
integrity_level(&self) -> IntegrityLevel443*bb4ee6a4SAndroid Build Coastguard Worker pub fn integrity_level(&self) -> IntegrityLevel {
444*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
445*bb4ee6a4SAndroid Build Coastguard Worker unsafe { bindings::sbox_get_integrity_level(self.policy.0) }
446*bb4ee6a4SAndroid Build Coastguard Worker }
447*bb4ee6a4SAndroid Build Coastguard Worker
448*bb4ee6a4SAndroid Build Coastguard Worker /// Specifies that the process should run on an alternate desktop. If
449*bb4ee6a4SAndroid Build Coastguard Worker /// `alternate_winstation` is set to `true`, the desktop will be created on an
450*bb4ee6a4SAndroid Build Coastguard Worker /// alternate windows station.
451*bb4ee6a4SAndroid Build Coastguard Worker ///
452*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_set_alternate_desktop` mutates the
453*bb4ee6a4SAndroid Build Coastguard Worker /// underlying policy object.
set_alternate_desktop(&mut self, alternate_winstation: bool) -> Result<()>454*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_alternate_desktop(&mut self, alternate_winstation: bool) -> Result<()> {
455*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
456*bb4ee6a4SAndroid Build Coastguard Worker match unsafe { bindings::sbox_set_alternate_desktop(self.policy.0, alternate_winstation) } {
457*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => Ok(()),
458*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
459*bb4ee6a4SAndroid Build Coastguard Worker }
460*bb4ee6a4SAndroid Build Coastguard Worker }
461*bb4ee6a4SAndroid Build Coastguard Worker
462*bb4ee6a4SAndroid Build Coastguard Worker /// Precreates the alternate desktop and winstation, if any.
463*bb4ee6a4SAndroid Build Coastguard Worker ///
464*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_create_alternate_desktop` mutates the
465*bb4ee6a4SAndroid Build Coastguard Worker /// underlying policy object.
create_alternate_desktop(&mut self, alternate_winstation: bool) -> Result<()>466*bb4ee6a4SAndroid Build Coastguard Worker pub fn create_alternate_desktop(&mut self, alternate_winstation: bool) -> Result<()> {
467*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
468*bb4ee6a4SAndroid Build Coastguard Worker match unsafe {
469*bb4ee6a4SAndroid Build Coastguard Worker bindings::sbox_create_alternate_desktop(self.policy.0, alternate_winstation)
470*bb4ee6a4SAndroid Build Coastguard Worker } {
471*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => Ok(()),
472*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
473*bb4ee6a4SAndroid Build Coastguard Worker }
474*bb4ee6a4SAndroid Build Coastguard Worker }
475*bb4ee6a4SAndroid Build Coastguard Worker
476*bb4ee6a4SAndroid Build Coastguard Worker /// Destroys the desktop and windows station.
477*bb4ee6a4SAndroid Build Coastguard Worker ///
478*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_destroy_alternate_desktop` mutates the
479*bb4ee6a4SAndroid Build Coastguard Worker /// underlying policy object.
destroy_alternate_desktop(&mut self)480*bb4ee6a4SAndroid Build Coastguard Worker pub fn destroy_alternate_desktop(&mut self) {
481*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
482*bb4ee6a4SAndroid Build Coastguard Worker unsafe { bindings::sbox_destroy_alternate_desktop(self.policy.0) }
483*bb4ee6a4SAndroid Build Coastguard Worker }
484*bb4ee6a4SAndroid Build Coastguard Worker
485*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the LowBox token for sandboxed process. This is mutually exclusive
486*bb4ee6a4SAndroid Build Coastguard Worker /// with the `add_app_container_profile()` method.
487*bb4ee6a4SAndroid Build Coastguard Worker ///
488*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_set_lowbox` mutates the underlying
489*bb4ee6a4SAndroid Build Coastguard Worker /// policy object.
set_lowbox(&mut self, sid: &str) -> Result<()>490*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_lowbox(&mut self, sid: &str) -> Result<()> {
491*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
492*bb4ee6a4SAndroid Build Coastguard Worker match unsafe { bindings::sbox_set_lowbox(self.policy.0, win32_wide_string(sid).as_ptr()) } {
493*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => Ok(()),
494*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
495*bb4ee6a4SAndroid Build Coastguard Worker }
496*bb4ee6a4SAndroid Build Coastguard Worker }
497*bb4ee6a4SAndroid Build Coastguard Worker
498*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the mitigations enabled when the process is created.
499*bb4ee6a4SAndroid Build Coastguard Worker ///
500*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_set_process_mitigations` mutates the
501*bb4ee6a4SAndroid Build Coastguard Worker /// underlying policy object.
set_process_mitigations(&mut self, flags: MitigationFlags) -> Result<()>502*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_process_mitigations(&mut self, flags: MitigationFlags) -> Result<()> {
503*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
504*bb4ee6a4SAndroid Build Coastguard Worker match unsafe { bindings::sbox_set_process_mitigations(self.policy.0, flags) } {
505*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => Ok(()),
506*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
507*bb4ee6a4SAndroid Build Coastguard Worker }
508*bb4ee6a4SAndroid Build Coastguard Worker }
509*bb4ee6a4SAndroid Build Coastguard Worker
510*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the currently set mitigation flags.
process_mitigations(&self) -> MitigationFlags511*bb4ee6a4SAndroid Build Coastguard Worker pub fn process_mitigations(&self) -> MitigationFlags {
512*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
513*bb4ee6a4SAndroid Build Coastguard Worker unsafe { bindings::sbox_get_process_mitigations(self.policy.0) }
514*bb4ee6a4SAndroid Build Coastguard Worker }
515*bb4ee6a4SAndroid Build Coastguard Worker
516*bb4ee6a4SAndroid Build Coastguard Worker /// Sets process mitigation flags that don't take effect before the call to
517*bb4ee6a4SAndroid Build Coastguard Worker /// lower_token().
518*bb4ee6a4SAndroid Build Coastguard Worker ///
519*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_set_delayed_process_mitigations`
520*bb4ee6a4SAndroid Build Coastguard Worker /// mutates the underlying policy object.
set_delayed_process_mitigations(&mut self, flags: MitigationFlags) -> Result<()>521*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_delayed_process_mitigations(&mut self, flags: MitigationFlags) -> Result<()> {
522*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
523*bb4ee6a4SAndroid Build Coastguard Worker match unsafe { bindings::sbox_set_delayed_process_mitigations(self.policy.0, flags) } {
524*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => Ok(()),
525*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
526*bb4ee6a4SAndroid Build Coastguard Worker }
527*bb4ee6a4SAndroid Build Coastguard Worker }
528*bb4ee6a4SAndroid Build Coastguard Worker
529*bb4ee6a4SAndroid Build Coastguard Worker /// Returns the currently set delayed_ mitigation flags.
delayed_process_mitigations(&self) -> MitigationFlags530*bb4ee6a4SAndroid Build Coastguard Worker pub fn delayed_process_mitigations(&self) -> MitigationFlags {
531*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
532*bb4ee6a4SAndroid Build Coastguard Worker unsafe { bindings::sbox_get_delayed_process_mitigations(self.policy.0) }
533*bb4ee6a4SAndroid Build Coastguard Worker }
534*bb4ee6a4SAndroid Build Coastguard Worker
535*bb4ee6a4SAndroid Build Coastguard Worker /// Disconnect the target from CSRSS when TargetServices::lower_token() is
536*bb4ee6a4SAndroid Build Coastguard Worker /// called inside the target.
537*bb4ee6a4SAndroid Build Coastguard Worker ///
538*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_set_disconnect_csrss` mutates the
539*bb4ee6a4SAndroid Build Coastguard Worker /// underlying policy object.
set_disconnect_csrss(&mut self) -> Result<()>540*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_disconnect_csrss(&mut self) -> Result<()> {
541*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
542*bb4ee6a4SAndroid Build Coastguard Worker match unsafe { bindings::sbox_set_disconnect_csrss(self.policy.0) } {
543*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => Ok(()),
544*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
545*bb4ee6a4SAndroid Build Coastguard Worker }
546*bb4ee6a4SAndroid Build Coastguard Worker }
547*bb4ee6a4SAndroid Build Coastguard Worker
548*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the interceptions to operate in strict mode.
549*bb4ee6a4SAndroid Build Coastguard Worker ///
550*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_set_delayed_process_mitigations`
551*bb4ee6a4SAndroid Build Coastguard Worker /// mutates the underlying policy object.
set_strict_interceptions(&mut self)552*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_strict_interceptions(&mut self) {
553*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
554*bb4ee6a4SAndroid Build Coastguard Worker unsafe { bindings::sbox_set_strict_interceptions(self.policy.0) }
555*bb4ee6a4SAndroid Build Coastguard Worker }
556*bb4ee6a4SAndroid Build Coastguard Worker
557*bb4ee6a4SAndroid Build Coastguard Worker /// Sets a file as the handle that the process should inherit for stdout.
set_stdout_from_file(&mut self, file: &'a std::fs::File) -> Result<()>558*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_stdout_from_file(&mut self, file: &'a std::fs::File) -> Result<()> {
559*bb4ee6a4SAndroid Build Coastguard Worker self.set_stdout_handle(file)
560*bb4ee6a4SAndroid Build Coastguard Worker }
561*bb4ee6a4SAndroid Build Coastguard Worker
562*bb4ee6a4SAndroid Build Coastguard Worker /// Sets a pipe as the handle that the process should inherit for stdout.
set_stdout_from_pipe(&mut self, pipe: &'a named_pipes::PipeConnection) -> Result<()>563*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_stdout_from_pipe(&mut self, pipe: &'a named_pipes::PipeConnection) -> Result<()> {
564*bb4ee6a4SAndroid Build Coastguard Worker self.set_stdout_handle(pipe)
565*bb4ee6a4SAndroid Build Coastguard Worker }
566*bb4ee6a4SAndroid Build Coastguard Worker
567*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the handle that the process should inherit for stdout.
568*bb4ee6a4SAndroid Build Coastguard Worker ///
569*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_set_stdout_handle()` mutates the underlying policy object.
set_stdout_handle(&mut self, handle: &'a dyn AsRawDescriptor) -> Result<()>570*bb4ee6a4SAndroid Build Coastguard Worker fn set_stdout_handle(&mut self, handle: &'a dyn AsRawDescriptor) -> Result<()> {
571*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
572*bb4ee6a4SAndroid Build Coastguard Worker match unsafe { bindings::sbox_set_stdout_handle(self.policy.0, handle.as_raw_descriptor()) }
573*bb4ee6a4SAndroid Build Coastguard Worker {
574*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => {
575*bb4ee6a4SAndroid Build Coastguard Worker win_util::set_handle_inheritance(
576*bb4ee6a4SAndroid Build Coastguard Worker handle.as_raw_descriptor(),
577*bb4ee6a4SAndroid Build Coastguard Worker /* inheritable= */ true,
578*bb4ee6a4SAndroid Build Coastguard Worker )?;
579*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
580*bb4ee6a4SAndroid Build Coastguard Worker }
581*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
582*bb4ee6a4SAndroid Build Coastguard Worker }
583*bb4ee6a4SAndroid Build Coastguard Worker }
584*bb4ee6a4SAndroid Build Coastguard Worker
585*bb4ee6a4SAndroid Build Coastguard Worker /// Sets a file as the handle that the process should inherit for stderr.
set_stderr_from_file(&mut self, file: &'a std::fs::File) -> Result<()>586*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_stderr_from_file(&mut self, file: &'a std::fs::File) -> Result<()> {
587*bb4ee6a4SAndroid Build Coastguard Worker self.set_stderr_handle(file)
588*bb4ee6a4SAndroid Build Coastguard Worker }
589*bb4ee6a4SAndroid Build Coastguard Worker
590*bb4ee6a4SAndroid Build Coastguard Worker /// Sets a pipe as the handle that the process should inherit for stderr.
set_stderr_from_pipe(&mut self, pipe: &'a named_pipes::PipeConnection) -> Result<()>591*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_stderr_from_pipe(&mut self, pipe: &'a named_pipes::PipeConnection) -> Result<()> {
592*bb4ee6a4SAndroid Build Coastguard Worker self.set_stderr_handle(pipe)
593*bb4ee6a4SAndroid Build Coastguard Worker }
594*bb4ee6a4SAndroid Build Coastguard Worker
595*bb4ee6a4SAndroid Build Coastguard Worker /// Sets the handle that the process should inherit for stderr.
596*bb4ee6a4SAndroid Build Coastguard Worker ///
597*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_set_stderr_handle` mutates the underlying policy object.
set_stderr_handle(&mut self, handle: &'a dyn AsRawDescriptor) -> Result<()>598*bb4ee6a4SAndroid Build Coastguard Worker fn set_stderr_handle(&mut self, handle: &'a dyn AsRawDescriptor) -> Result<()> {
599*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
600*bb4ee6a4SAndroid Build Coastguard Worker match unsafe { bindings::sbox_set_stderr_handle(self.policy.0, handle.as_raw_descriptor()) }
601*bb4ee6a4SAndroid Build Coastguard Worker {
602*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => {
603*bb4ee6a4SAndroid Build Coastguard Worker win_util::set_handle_inheritance(
604*bb4ee6a4SAndroid Build Coastguard Worker handle.as_raw_descriptor(),
605*bb4ee6a4SAndroid Build Coastguard Worker /* inheritable= */ true,
606*bb4ee6a4SAndroid Build Coastguard Worker )?;
607*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
608*bb4ee6a4SAndroid Build Coastguard Worker }
609*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
610*bb4ee6a4SAndroid Build Coastguard Worker }
611*bb4ee6a4SAndroid Build Coastguard Worker }
612*bb4ee6a4SAndroid Build Coastguard Worker
613*bb4ee6a4SAndroid Build Coastguard Worker /// Adds a policy rule effective for processes spawned using this policy.
614*bb4ee6a4SAndroid Build Coastguard Worker ///
615*bb4ee6a4SAndroid Build Coastguard Worker /// # Arguments:
616*bb4ee6a4SAndroid Build Coastguard Worker ///
617*bb4ee6a4SAndroid Build Coastguard Worker /// * subsystem: One of the enumerated Subsystems.
618*bb4ee6a4SAndroid Build Coastguard Worker /// * semantics: One of the enumerated Semantics.
619*bb4ee6a4SAndroid Build Coastguard Worker /// * pattern: A specific full path or a full path with wildcard patterns.
620*bb4ee6a4SAndroid Build Coastguard Worker ///
621*bb4ee6a4SAndroid Build Coastguard Worker /// The valid wildcards are:
622*bb4ee6a4SAndroid Build Coastguard Worker /// * `*`: Matches zero or more character. Only one in series allowed.
623*bb4ee6a4SAndroid Build Coastguard Worker /// * `?`: Matches a single character. One or more in series are allowed.
624*bb4ee6a4SAndroid Build Coastguard Worker ///
625*bb4ee6a4SAndroid Build Coastguard Worker /// Examples:
626*bb4ee6a4SAndroid Build Coastguard Worker /// * `"c:\\documents and settings\\vince\\*.dmp"`
627*bb4ee6a4SAndroid Build Coastguard Worker /// * `"c:\\documents and settings\\*\\crashdumps\\*.dmp"`
628*bb4ee6a4SAndroid Build Coastguard Worker /// * `"c:\\temp\\app_log_?????_chrome.txt"`
629*bb4ee6a4SAndroid Build Coastguard Worker ///
630*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_add_rule` mutates the underlying
631*bb4ee6a4SAndroid Build Coastguard Worker /// policy object.
add_rule<T: AsRef<str>>( &mut self, subsystem: SubSystem, semantics: Semantics, pattern: T, ) -> Result<()>632*bb4ee6a4SAndroid Build Coastguard Worker pub fn add_rule<T: AsRef<str>>(
633*bb4ee6a4SAndroid Build Coastguard Worker &mut self,
634*bb4ee6a4SAndroid Build Coastguard Worker subsystem: SubSystem,
635*bb4ee6a4SAndroid Build Coastguard Worker semantics: Semantics,
636*bb4ee6a4SAndroid Build Coastguard Worker pattern: T,
637*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<()> {
638*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
639*bb4ee6a4SAndroid Build Coastguard Worker // The function does not modify the pattern pointer, so that usage is safe.
640*bb4ee6a4SAndroid Build Coastguard Worker match unsafe {
641*bb4ee6a4SAndroid Build Coastguard Worker bindings::sbox_add_rule(
642*bb4ee6a4SAndroid Build Coastguard Worker self.policy.0,
643*bb4ee6a4SAndroid Build Coastguard Worker subsystem,
644*bb4ee6a4SAndroid Build Coastguard Worker semantics,
645*bb4ee6a4SAndroid Build Coastguard Worker win32_wide_string(pattern.as_ref()).as_ptr(),
646*bb4ee6a4SAndroid Build Coastguard Worker )
647*bb4ee6a4SAndroid Build Coastguard Worker } {
648*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => Ok(()),
649*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
650*bb4ee6a4SAndroid Build Coastguard Worker }
651*bb4ee6a4SAndroid Build Coastguard Worker }
652*bb4ee6a4SAndroid Build Coastguard Worker
653*bb4ee6a4SAndroid Build Coastguard Worker /// Adds a dll that will be unloaded in the target process before it gets
654*bb4ee6a4SAndroid Build Coastguard Worker /// a chance to initialize itself.
655*bb4ee6a4SAndroid Build Coastguard Worker ///
656*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_add_dll_to_unload` mutates the
657*bb4ee6a4SAndroid Build Coastguard Worker /// underlying policy object.
add_dll_to_unload(&mut self, dll_name: &str) -> Result<()>658*bb4ee6a4SAndroid Build Coastguard Worker pub fn add_dll_to_unload(&mut self, dll_name: &str) -> Result<()> {
659*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
660*bb4ee6a4SAndroid Build Coastguard Worker // The function does not modify the dll_name pointer, so that usage is safe.
661*bb4ee6a4SAndroid Build Coastguard Worker match unsafe {
662*bb4ee6a4SAndroid Build Coastguard Worker bindings::sbox_add_dll_to_unload(self.policy.0, win32_wide_string(dll_name).as_ptr())
663*bb4ee6a4SAndroid Build Coastguard Worker } {
664*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => Ok(()),
665*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
666*bb4ee6a4SAndroid Build Coastguard Worker }
667*bb4ee6a4SAndroid Build Coastguard Worker }
668*bb4ee6a4SAndroid Build Coastguard Worker
669*bb4ee6a4SAndroid Build Coastguard Worker /// Adds a handle that will be closed in the target process after lockdown.
670*bb4ee6a4SAndroid Build Coastguard Worker /// Specifying `None` for `handle_name` indicates all handles of the specified
671*bb4ee6a4SAndroid Build Coastguard Worker /// type. An empty string for `handle_name` indicates the handle is unnamed.
672*bb4ee6a4SAndroid Build Coastguard Worker ///
673*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_add_kernel_object_to_close` mutates the
674*bb4ee6a4SAndroid Build Coastguard Worker /// underlying policy object.
add_kernel_object_to_close( &mut self, handle_type: &str, handle_name: Option<&str>, ) -> Result<()>675*bb4ee6a4SAndroid Build Coastguard Worker pub fn add_kernel_object_to_close(
676*bb4ee6a4SAndroid Build Coastguard Worker &mut self,
677*bb4ee6a4SAndroid Build Coastguard Worker handle_type: &str,
678*bb4ee6a4SAndroid Build Coastguard Worker handle_name: Option<&str>,
679*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<()> {
680*bb4ee6a4SAndroid Build Coastguard Worker let handle_name_wide = handle_name.map(win32_wide_string);
681*bb4ee6a4SAndroid Build Coastguard Worker let handle_name_ptr = handle_name_wide
682*bb4ee6a4SAndroid Build Coastguard Worker .as_ref()
683*bb4ee6a4SAndroid Build Coastguard Worker .map_or(std::ptr::null(), Vec::<u16>::as_ptr);
684*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
685*bb4ee6a4SAndroid Build Coastguard Worker // The function does not modify either of the string pointers, so that usage is safe.
686*bb4ee6a4SAndroid Build Coastguard Worker // The function safely handles null pointers for the handle name.
687*bb4ee6a4SAndroid Build Coastguard Worker match unsafe {
688*bb4ee6a4SAndroid Build Coastguard Worker bindings::sbox_add_kernel_object_to_close(
689*bb4ee6a4SAndroid Build Coastguard Worker self.policy.0,
690*bb4ee6a4SAndroid Build Coastguard Worker win32_wide_string(handle_type).as_ptr(),
691*bb4ee6a4SAndroid Build Coastguard Worker handle_name_ptr,
692*bb4ee6a4SAndroid Build Coastguard Worker )
693*bb4ee6a4SAndroid Build Coastguard Worker } {
694*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => Ok(()),
695*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
696*bb4ee6a4SAndroid Build Coastguard Worker }
697*bb4ee6a4SAndroid Build Coastguard Worker }
698*bb4ee6a4SAndroid Build Coastguard Worker
699*bb4ee6a4SAndroid Build Coastguard Worker /// Adds a handle that will be shared with the target process.
700*bb4ee6a4SAndroid Build Coastguard Worker ///
701*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_add_handle_to_share()` mutates the underlying policy
702*bb4ee6a4SAndroid Build Coastguard Worker /// object.
add_handle_to_share(&mut self, handle: &'a dyn AsRawDescriptor)703*bb4ee6a4SAndroid Build Coastguard Worker pub fn add_handle_to_share(&mut self, handle: &'a dyn AsRawDescriptor) {
704*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
705*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
706*bb4ee6a4SAndroid Build Coastguard Worker bindings::sbox_add_handle_to_share(self.policy.0, handle.as_raw_descriptor());
707*bb4ee6a4SAndroid Build Coastguard Worker }
708*bb4ee6a4SAndroid Build Coastguard Worker }
709*bb4ee6a4SAndroid Build Coastguard Worker
710*bb4ee6a4SAndroid Build Coastguard Worker /// Locks down the default DACL of the created lockdown and initial tokens
711*bb4ee6a4SAndroid Build Coastguard Worker /// to restrict what other processes are allowed to access a process' kernel
712*bb4ee6a4SAndroid Build Coastguard Worker /// resources.
713*bb4ee6a4SAndroid Build Coastguard Worker ///
714*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_set_lockdown_default_dacl()` mutates
715*bb4ee6a4SAndroid Build Coastguard Worker /// the underlying policy object.
set_lockdown_default_dacl(&mut self)716*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_lockdown_default_dacl(&mut self) {
717*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
718*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
719*bb4ee6a4SAndroid Build Coastguard Worker bindings::sbox_set_lockdown_default_dacl(self.policy.0);
720*bb4ee6a4SAndroid Build Coastguard Worker }
721*bb4ee6a4SAndroid Build Coastguard Worker }
722*bb4ee6a4SAndroid Build Coastguard Worker
723*bb4ee6a4SAndroid Build Coastguard Worker /// Adds a restricting random SID to the restricted SIDs list as well as
724*bb4ee6a4SAndroid Build Coastguard Worker /// the default DACL.
725*bb4ee6a4SAndroid Build Coastguard Worker ///
726*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_add_restricting_random_sid()` mutates
727*bb4ee6a4SAndroid Build Coastguard Worker /// the underlying policy object.
add_restricting_random_sid(&mut self)728*bb4ee6a4SAndroid Build Coastguard Worker pub fn add_restricting_random_sid(&mut self) {
729*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
730*bb4ee6a4SAndroid Build Coastguard Worker unsafe {
731*bb4ee6a4SAndroid Build Coastguard Worker bindings::sbox_add_restricting_random_sid(self.policy.0);
732*bb4ee6a4SAndroid Build Coastguard Worker }
733*bb4ee6a4SAndroid Build Coastguard Worker }
734*bb4ee6a4SAndroid Build Coastguard Worker
735*bb4ee6a4SAndroid Build Coastguard Worker /// Configure policy to use an AppContainer profile.
736*bb4ee6a4SAndroid Build Coastguard Worker ///
737*bb4ee6a4SAndroid Build Coastguard Worker /// # Arguments:
738*bb4ee6a4SAndroid Build Coastguard Worker /// * `package_name`: the name of the profile to use.
739*bb4ee6a4SAndroid Build Coastguard Worker /// * `create_profile`: Specifying `true` for `create_profile` ensures the profile exists, if
740*bb4ee6a4SAndroid Build Coastguard Worker /// set to `false` process creation will fail if the profile has not already been created.
741*bb4ee6a4SAndroid Build Coastguard Worker ///
742*bb4ee6a4SAndroid Build Coastguard Worker /// Takes a `&mut self` because `sbox_add_dll_to_unload` mutates the
743*bb4ee6a4SAndroid Build Coastguard Worker /// underlying policy object.
add_app_container_profile( &mut self, package_name: &str, create_profile: bool, ) -> Result<()>744*bb4ee6a4SAndroid Build Coastguard Worker pub fn add_app_container_profile(
745*bb4ee6a4SAndroid Build Coastguard Worker &mut self,
746*bb4ee6a4SAndroid Build Coastguard Worker package_name: &str,
747*bb4ee6a4SAndroid Build Coastguard Worker create_profile: bool,
748*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<()> {
749*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null policy pointer.
750*bb4ee6a4SAndroid Build Coastguard Worker // The function does not modify the package_name pointer, so that usage is safe.
751*bb4ee6a4SAndroid Build Coastguard Worker match unsafe {
752*bb4ee6a4SAndroid Build Coastguard Worker bindings::sbox_add_app_container_profile(
753*bb4ee6a4SAndroid Build Coastguard Worker self.policy.0,
754*bb4ee6a4SAndroid Build Coastguard Worker win32_wide_string(package_name).as_ptr(),
755*bb4ee6a4SAndroid Build Coastguard Worker create_profile,
756*bb4ee6a4SAndroid Build Coastguard Worker )
757*bb4ee6a4SAndroid Build Coastguard Worker } {
758*bb4ee6a4SAndroid Build Coastguard Worker ResultCode::SBOX_ALL_OK => Ok(()),
759*bb4ee6a4SAndroid Build Coastguard Worker result_code => Err(SandboxError::new(result_code)),
760*bb4ee6a4SAndroid Build Coastguard Worker }
761*bb4ee6a4SAndroid Build Coastguard Worker }
762*bb4ee6a4SAndroid Build Coastguard Worker
763*bb4ee6a4SAndroid Build Coastguard Worker /// Returns a snapshot of the policy configuration.
policy_info(&self) -> PolicyInfo764*bb4ee6a4SAndroid Build Coastguard Worker pub fn policy_info(&self) -> PolicyInfo {
765*bb4ee6a4SAndroid Build Coastguard Worker // Safe because TargetPolicy can only be constructed with a non-null
766*bb4ee6a4SAndroid Build Coastguard Worker // policy pointer. The underlying PolicyInfo object contains a copy of
767*bb4ee6a4SAndroid Build Coastguard Worker // the data from the TargetPolicy object, but does not hold any
768*bb4ee6a4SAndroid Build Coastguard Worker // references to it, so the lifetimes are independent.
769*bb4ee6a4SAndroid Build Coastguard Worker PolicyInfo {
770*bb4ee6a4SAndroid Build Coastguard Worker policy_info: unsafe { bindings::sbox_get_policy_info(self.policy.0) },
771*bb4ee6a4SAndroid Build Coastguard Worker }
772*bb4ee6a4SAndroid Build Coastguard Worker }
773*bb4ee6a4SAndroid Build Coastguard Worker }
774*bb4ee6a4SAndroid Build Coastguard Worker
775*bb4ee6a4SAndroid Build Coastguard Worker impl PolicyInfo {
776*bb4ee6a4SAndroid Build Coastguard Worker /// Returns a JSON representation of the policy snapshot.
777*bb4ee6a4SAndroid Build Coastguard Worker /// This pointer has the same lifetime as the PolicyInfo object.
json(&self) -> &str778*bb4ee6a4SAndroid Build Coastguard Worker pub fn json(&self) -> &str {
779*bb4ee6a4SAndroid Build Coastguard Worker // Safe because PolicyInfo can only be constructed with a non-null
780*bb4ee6a4SAndroid Build Coastguard Worker // policy pointer. The string returned will be a valid pointer to a
781*bb4ee6a4SAndroid Build Coastguard Worker // valid c string. We bind the lifetime of the string to the lifetime
782*bb4ee6a4SAndroid Build Coastguard Worker // of the PolicyInfo object, as is guaranteed by the underlying
783*bb4ee6a4SAndroid Build Coastguard Worker // library. This is a string representation of a snapshot of the
784*bb4ee6a4SAndroid Build Coastguard Worker // policy, so it will not change.
785*bb4ee6a4SAndroid Build Coastguard Worker let c_str =
786*bb4ee6a4SAndroid Build Coastguard Worker unsafe { CStr::from_ptr(bindings::sbox_policy_info_json_string(self.policy_info)) };
787*bb4ee6a4SAndroid Build Coastguard Worker c_str.to_str().unwrap()
788*bb4ee6a4SAndroid Build Coastguard Worker }
789*bb4ee6a4SAndroid Build Coastguard Worker }
790*bb4ee6a4SAndroid Build Coastguard Worker
791*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b/196996588): Develop more tests, especially policy-related, once we
792*bb4ee6a4SAndroid Build Coastguard Worker // have a way to launch and test target processes.
793*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)]
794*bb4ee6a4SAndroid Build Coastguard Worker mod tests {
795*bb4ee6a4SAndroid Build Coastguard Worker use super::*;
796*bb4ee6a4SAndroid Build Coastguard Worker
797*bb4ee6a4SAndroid Build Coastguard Worker #[test]
not_the_target()798*bb4ee6a4SAndroid Build Coastguard Worker fn not_the_target() {
799*bb4ee6a4SAndroid Build Coastguard Worker let target = TargetServices::get().unwrap();
800*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(target, None);
801*bb4ee6a4SAndroid Build Coastguard Worker }
802*bb4ee6a4SAndroid Build Coastguard Worker
803*bb4ee6a4SAndroid Build Coastguard Worker #[test]
is_the_broker()804*bb4ee6a4SAndroid Build Coastguard Worker fn is_the_broker() {
805*bb4ee6a4SAndroid Build Coastguard Worker let broker = BrokerServices::get().unwrap();
806*bb4ee6a4SAndroid Build Coastguard Worker assert_ne!(broker, None);
807*bb4ee6a4SAndroid Build Coastguard Worker }
808*bb4ee6a4SAndroid Build Coastguard Worker
809*bb4ee6a4SAndroid Build Coastguard Worker #[test]
policy_handles_live_long_enough()810*bb4ee6a4SAndroid Build Coastguard Worker fn policy_handles_live_long_enough() {
811*bb4ee6a4SAndroid Build Coastguard Worker let broker = BrokerServices::get().unwrap().unwrap();
812*bb4ee6a4SAndroid Build Coastguard Worker let mut policy = broker.create_policy();
813*bb4ee6a4SAndroid Build Coastguard Worker let pipe = named_pipes::pair(
814*bb4ee6a4SAndroid Build Coastguard Worker &named_pipes::FramingMode::Byte,
815*bb4ee6a4SAndroid Build Coastguard Worker &named_pipes::BlockingMode::NoWait,
816*bb4ee6a4SAndroid Build Coastguard Worker 0,
817*bb4ee6a4SAndroid Build Coastguard Worker )
818*bb4ee6a4SAndroid Build Coastguard Worker .unwrap();
819*bb4ee6a4SAndroid Build Coastguard Worker policy.set_stdout_handle(&pipe.0).unwrap();
820*bb4ee6a4SAndroid Build Coastguard Worker policy.set_stderr_handle(&pipe.0).unwrap();
821*bb4ee6a4SAndroid Build Coastguard Worker policy.add_handle_to_share(&pipe.0);
822*bb4ee6a4SAndroid Build Coastguard Worker }
823*bb4ee6a4SAndroid Build Coastguard Worker }
824