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 use std::alloc::alloc_zeroed; 6*bb4ee6a4SAndroid Build Coastguard Worker use std::alloc::dealloc; 7*bb4ee6a4SAndroid Build Coastguard Worker use std::alloc::handle_alloc_error; 8*bb4ee6a4SAndroid Build Coastguard Worker use std::alloc::Layout; 9*bb4ee6a4SAndroid Build Coastguard Worker use std::convert::TryFrom; 10*bb4ee6a4SAndroid Build Coastguard Worker use std::convert::TryInto; 11*bb4ee6a4SAndroid Build Coastguard Worker use std::io; 12*bb4ee6a4SAndroid Build Coastguard Worker use std::mem::size_of; 13*bb4ee6a4SAndroid Build Coastguard Worker use std::os::windows::io::RawHandle; 14*bb4ee6a4SAndroid Build Coastguard Worker use std::ptr; 15*bb4ee6a4SAndroid Build Coastguard Worker 16*bb4ee6a4SAndroid Build Coastguard Worker use once_cell::sync::OnceCell; 17*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::minwindef::FALSE; 18*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::minwindef::HLOCAL; 19*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::minwindef::LPDWORD; 20*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::minwindef::LPVOID; 21*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::minwindef::TRUE; 22*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::winerror::ERROR_INSUFFICIENT_BUFFER; 23*bb4ee6a4SAndroid Build Coastguard Worker use winapi::shared::winerror::ERROR_SUCCESS; 24*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::EXPLICIT_ACCESS_A; 25*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::NO_INHERITANCE; 26*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::NO_MULTIPLE_TRUSTEE; 27*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::PEXPLICIT_ACCESSA; 28*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::SET_ACCESS; 29*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::TRUSTEE_A; 30*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::TRUSTEE_IS_SID; 31*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::accctrl::TRUSTEE_IS_USER; 32*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::aclapi::SetEntriesInAclA; 33*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::handleapi::CloseHandle; 34*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::minwinbase::SECURITY_ATTRIBUTES; 35*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::processthreadsapi::GetCurrentProcess; 36*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::processthreadsapi::OpenProcessToken; 37*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::processthreadsapi::OpenThreadToken; 38*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::securitybaseapi::GetTokenInformation; 39*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::securitybaseapi::InitializeSecurityDescriptor; 40*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::securitybaseapi::MakeSelfRelativeSD; 41*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::securitybaseapi::SetSecurityDescriptorDacl; 42*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winbase::LocalFree; 43*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TokenIntegrityLevel; 44*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TokenStatistics; 45*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TokenUser; 46*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::ACL; 47*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::GENERIC_ALL; 48*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::PACL; 49*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::PSECURITY_DESCRIPTOR; 50*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::SECURITY_DESCRIPTOR; 51*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::SECURITY_DESCRIPTOR_REVISION; 52*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TOKEN_ALL_ACCESS; 53*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TOKEN_INFORMATION_CLASS; 54*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TOKEN_MANDATORY_LABEL; 55*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TOKEN_STATISTICS; 56*bb4ee6a4SAndroid Build Coastguard Worker use winapi::um::winnt::TOKEN_USER; 57*bb4ee6a4SAndroid Build Coastguard Worker 58*bb4ee6a4SAndroid Build Coastguard Worker /// Struct for wrapping `SECURITY_ATTRIBUTES` and `SECURITY_DESCRIPTOR`. 59*bb4ee6a4SAndroid Build Coastguard Worker pub struct SecurityAttributes<T: SecurityDescriptor> { 60*bb4ee6a4SAndroid Build Coastguard Worker // The security descriptor shouldn't move, as it will be referenced by the 61*bb4ee6a4SAndroid Build Coastguard Worker // security attributes. We already limit what can be done with the security 62*bb4ee6a4SAndroid Build Coastguard Worker // attributes by only providing a reference to it, but we also want to 63*bb4ee6a4SAndroid Build Coastguard Worker // ensure the security descriptor pointer remains valid even if this struct 64*bb4ee6a4SAndroid Build Coastguard Worker // moves around. 65*bb4ee6a4SAndroid Build Coastguard Worker _security_descriptor: T, 66*bb4ee6a4SAndroid Build Coastguard Worker security_attributes: SECURITY_ATTRIBUTES, 67*bb4ee6a4SAndroid Build Coastguard Worker } 68*bb4ee6a4SAndroid Build Coastguard Worker 69*bb4ee6a4SAndroid Build Coastguard Worker impl<T: SecurityDescriptor> SecurityAttributes<T> { 70*bb4ee6a4SAndroid Build Coastguard Worker /// Create a new `SecurityAttributes` struct with the provided `security_descriptor`. new_with_security_descriptor(security_descriptor: T, inherit: bool) -> Self71*bb4ee6a4SAndroid Build Coastguard Worker pub fn new_with_security_descriptor(security_descriptor: T, inherit: bool) -> Self { 72*bb4ee6a4SAndroid Build Coastguard Worker let sd = security_descriptor.security_descriptor(); 73*bb4ee6a4SAndroid Build Coastguard Worker let security_attributes = SECURITY_ATTRIBUTES { 74*bb4ee6a4SAndroid Build Coastguard Worker nLength: size_of::<SECURITY_ATTRIBUTES>() as u32, 75*bb4ee6a4SAndroid Build Coastguard Worker lpSecurityDescriptor: sd as PSECURITY_DESCRIPTOR, 76*bb4ee6a4SAndroid Build Coastguard Worker bInheritHandle: if inherit { TRUE } else { FALSE }, 77*bb4ee6a4SAndroid Build Coastguard Worker }; 78*bb4ee6a4SAndroid Build Coastguard Worker SecurityAttributes { 79*bb4ee6a4SAndroid Build Coastguard Worker _security_descriptor: security_descriptor, 80*bb4ee6a4SAndroid Build Coastguard Worker security_attributes, 81*bb4ee6a4SAndroid Build Coastguard Worker } 82*bb4ee6a4SAndroid Build Coastguard Worker } 83*bb4ee6a4SAndroid Build Coastguard Worker } 84*bb4ee6a4SAndroid Build Coastguard Worker 85*bb4ee6a4SAndroid Build Coastguard Worker impl SecurityAttributes<SelfRelativeSecurityDescriptor> { 86*bb4ee6a4SAndroid Build Coastguard Worker /// Create a new `SecurityAttributes` struct. This struct will have a 87*bb4ee6a4SAndroid Build Coastguard Worker /// `SECURITY_DESCRIPTOR` that allows full access (`GENERIC_ALL`) to only 88*bb4ee6a4SAndroid Build Coastguard Worker /// the current user. new(inherit: bool) -> io::Result<Self>89*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(inherit: bool) -> io::Result<Self> { 90*bb4ee6a4SAndroid Build Coastguard Worker Ok(Self::new_with_security_descriptor( 91*bb4ee6a4SAndroid Build Coastguard Worker SelfRelativeSecurityDescriptor::new()?, 92*bb4ee6a4SAndroid Build Coastguard Worker inherit, 93*bb4ee6a4SAndroid Build Coastguard Worker )) 94*bb4ee6a4SAndroid Build Coastguard Worker } 95*bb4ee6a4SAndroid Build Coastguard Worker } 96*bb4ee6a4SAndroid Build Coastguard Worker 97*bb4ee6a4SAndroid Build Coastguard Worker impl<T: SecurityDescriptor> AsRef<SECURITY_ATTRIBUTES> for SecurityAttributes<T> { as_ref(&self) -> &SECURITY_ATTRIBUTES98*bb4ee6a4SAndroid Build Coastguard Worker fn as_ref(&self) -> &SECURITY_ATTRIBUTES { 99*bb4ee6a4SAndroid Build Coastguard Worker &self.security_attributes 100*bb4ee6a4SAndroid Build Coastguard Worker } 101*bb4ee6a4SAndroid Build Coastguard Worker } 102*bb4ee6a4SAndroid Build Coastguard Worker 103*bb4ee6a4SAndroid Build Coastguard Worker impl<T: SecurityDescriptor> AsMut<SECURITY_ATTRIBUTES> for SecurityAttributes<T> { as_mut(&mut self) -> &mut SECURITY_ATTRIBUTES104*bb4ee6a4SAndroid Build Coastguard Worker fn as_mut(&mut self) -> &mut SECURITY_ATTRIBUTES { 105*bb4ee6a4SAndroid Build Coastguard Worker &mut self.security_attributes 106*bb4ee6a4SAndroid Build Coastguard Worker } 107*bb4ee6a4SAndroid Build Coastguard Worker } 108*bb4ee6a4SAndroid Build Coastguard Worker 109*bb4ee6a4SAndroid Build Coastguard Worker pub trait TokenClass { class() -> TOKEN_INFORMATION_CLASS110*bb4ee6a4SAndroid Build Coastguard Worker fn class() -> TOKEN_INFORMATION_CLASS; 111*bb4ee6a4SAndroid Build Coastguard Worker } 112*bb4ee6a4SAndroid Build Coastguard Worker 113*bb4ee6a4SAndroid Build Coastguard Worker impl TokenClass for TOKEN_MANDATORY_LABEL { class() -> TOKEN_INFORMATION_CLASS114*bb4ee6a4SAndroid Build Coastguard Worker fn class() -> TOKEN_INFORMATION_CLASS { 115*bb4ee6a4SAndroid Build Coastguard Worker TokenIntegrityLevel 116*bb4ee6a4SAndroid Build Coastguard Worker } 117*bb4ee6a4SAndroid Build Coastguard Worker } 118*bb4ee6a4SAndroid Build Coastguard Worker 119*bb4ee6a4SAndroid Build Coastguard Worker impl TokenClass for TOKEN_STATISTICS { class() -> TOKEN_INFORMATION_CLASS120*bb4ee6a4SAndroid Build Coastguard Worker fn class() -> TOKEN_INFORMATION_CLASS { 121*bb4ee6a4SAndroid Build Coastguard Worker TokenStatistics 122*bb4ee6a4SAndroid Build Coastguard Worker } 123*bb4ee6a4SAndroid Build Coastguard Worker } 124*bb4ee6a4SAndroid Build Coastguard Worker 125*bb4ee6a4SAndroid Build Coastguard Worker impl TokenClass for TOKEN_USER { class() -> TOKEN_INFORMATION_CLASS126*bb4ee6a4SAndroid Build Coastguard Worker fn class() -> TOKEN_INFORMATION_CLASS { 127*bb4ee6a4SAndroid Build Coastguard Worker TokenUser 128*bb4ee6a4SAndroid Build Coastguard Worker } 129*bb4ee6a4SAndroid Build Coastguard Worker } 130*bb4ee6a4SAndroid Build Coastguard Worker 131*bb4ee6a4SAndroid Build Coastguard Worker pub struct TokenInformation<T> { 132*bb4ee6a4SAndroid Build Coastguard Worker token_info: *mut T, 133*bb4ee6a4SAndroid Build Coastguard Worker layout: Layout, 134*bb4ee6a4SAndroid Build Coastguard Worker } 135*bb4ee6a4SAndroid Build Coastguard Worker 136*bb4ee6a4SAndroid Build Coastguard Worker impl<T: TokenClass> TokenInformation<T> { new(mut token: Token) -> io::Result<Self>137*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(mut token: Token) -> io::Result<Self> { 138*bb4ee6a4SAndroid Build Coastguard Worker let token_handle = token.get(); 139*bb4ee6a4SAndroid Build Coastguard Worker // Retrieve the size of the struct. 140*bb4ee6a4SAndroid Build Coastguard Worker let mut size: u32 = 0; 141*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: size is valid, and TokenInformation is optional and allowed to be null. 142*bb4ee6a4SAndroid Build Coastguard Worker if unsafe { 143*bb4ee6a4SAndroid Build Coastguard Worker // The idiomatic usage of GetTokenInformation() requires two calls 144*bb4ee6a4SAndroid Build Coastguard Worker // to the function: the first to get the length of the data that the 145*bb4ee6a4SAndroid Build Coastguard Worker // function would return, and the second to fetch the data. 146*bb4ee6a4SAndroid Build Coastguard Worker GetTokenInformation( 147*bb4ee6a4SAndroid Build Coastguard Worker /* TokenHandle= */ token_handle, 148*bb4ee6a4SAndroid Build Coastguard Worker /* TokenInformationClass= */ T::class(), 149*bb4ee6a4SAndroid Build Coastguard Worker /* TokenInformation= */ ptr::null_mut(), 150*bb4ee6a4SAndroid Build Coastguard Worker /* TokenInformationLength= */ 0, 151*bb4ee6a4SAndroid Build Coastguard Worker /* ReturnLength= */ &mut size, 152*bb4ee6a4SAndroid Build Coastguard Worker ) == 0 153*bb4ee6a4SAndroid Build Coastguard Worker } { 154*bb4ee6a4SAndroid Build Coastguard Worker const INSUFFICIENT_BUFFER: i32 = ERROR_INSUFFICIENT_BUFFER as i32; 155*bb4ee6a4SAndroid Build Coastguard Worker match io::Error::last_os_error().raw_os_error() { 156*bb4ee6a4SAndroid Build Coastguard Worker Some(INSUFFICIENT_BUFFER) => { 157*bb4ee6a4SAndroid Build Coastguard Worker // Despite returning failure, the function will fill in the 158*bb4ee6a4SAndroid Build Coastguard Worker // expected buffer length into the ReturnLength parameter. 159*bb4ee6a4SAndroid Build Coastguard Worker // It may fail in other ways (e.g. if an invalid TokenHandle 160*bb4ee6a4SAndroid Build Coastguard Worker // is provided), so we check that we receive the expected 161*bb4ee6a4SAndroid Build Coastguard Worker // error code before assuming that we received a valid 162*bb4ee6a4SAndroid Build Coastguard Worker // ReturnLength. In this case, we can ignore the error. 163*bb4ee6a4SAndroid Build Coastguard Worker } 164*bb4ee6a4SAndroid Build Coastguard Worker _ => return Err(io::Error::last_os_error()), 165*bb4ee6a4SAndroid Build Coastguard Worker }; 166*bb4ee6a4SAndroid Build Coastguard Worker } 167*bb4ee6a4SAndroid Build Coastguard Worker 168*bb4ee6a4SAndroid Build Coastguard Worker // size must be > 0. 0-sized layouts break alloc()'s assumptions. 169*bb4ee6a4SAndroid Build Coastguard Worker assert!(size > 0, "Unable to get size of token information"); 170*bb4ee6a4SAndroid Build Coastguard Worker 171*bb4ee6a4SAndroid Build Coastguard Worker // Since we don't statically know the full size of the struct, we 172*bb4ee6a4SAndroid Build Coastguard Worker // allocate memory for it based on the previous call, aligned to pointer 173*bb4ee6a4SAndroid Build Coastguard Worker // size. 174*bb4ee6a4SAndroid Build Coastguard Worker let layout = Layout::from_size_align(size as usize, size_of::<LPVOID>()) 175*bb4ee6a4SAndroid Build Coastguard Worker .expect("Failed to create layout"); 176*bb4ee6a4SAndroid Build Coastguard Worker assert!(layout.size() > 0, "Failed to create valid layout"); 177*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: We assert that layout's size is non-zero. 178*bb4ee6a4SAndroid Build Coastguard Worker let token_info = unsafe { alloc_zeroed(layout) } as *mut T; 179*bb4ee6a4SAndroid Build Coastguard Worker if token_info.is_null() { 180*bb4ee6a4SAndroid Build Coastguard Worker handle_alloc_error(layout); 181*bb4ee6a4SAndroid Build Coastguard Worker } 182*bb4ee6a4SAndroid Build Coastguard Worker 183*bb4ee6a4SAndroid Build Coastguard Worker let token_info = TokenInformation::<T> { token_info, layout }; 184*bb4ee6a4SAndroid Build Coastguard Worker 185*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: token_user and size are valid. 186*bb4ee6a4SAndroid Build Coastguard Worker if unsafe { 187*bb4ee6a4SAndroid Build Coastguard Worker GetTokenInformation( 188*bb4ee6a4SAndroid Build Coastguard Worker /* TokenHandle= */ token_handle, 189*bb4ee6a4SAndroid Build Coastguard Worker /* TokenInformationClass= */ T::class(), 190*bb4ee6a4SAndroid Build Coastguard Worker /* TokenInformation= */ token_info.token_info as LPVOID, 191*bb4ee6a4SAndroid Build Coastguard Worker /* TokenInformationLength= */ size, 192*bb4ee6a4SAndroid Build Coastguard Worker /* ReturnLength= */ &mut size, 193*bb4ee6a4SAndroid Build Coastguard Worker ) == 0 194*bb4ee6a4SAndroid Build Coastguard Worker } { 195*bb4ee6a4SAndroid Build Coastguard Worker return Err(io::Error::last_os_error()); 196*bb4ee6a4SAndroid Build Coastguard Worker } 197*bb4ee6a4SAndroid Build Coastguard Worker 198*bb4ee6a4SAndroid Build Coastguard Worker Ok(token_info) 199*bb4ee6a4SAndroid Build Coastguard Worker } 200*bb4ee6a4SAndroid Build Coastguard Worker } 201*bb4ee6a4SAndroid Build Coastguard Worker 202*bb4ee6a4SAndroid Build Coastguard Worker impl<T> AsRef<T> for TokenInformation<T> { as_ref(&self) -> &T203*bb4ee6a4SAndroid Build Coastguard Worker fn as_ref(&self) -> &T { 204*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: The underlying pointer is guaranteed to be properly aligned, dereferenceable, and 205*bb4ee6a4SAndroid Build Coastguard Worker // point to a valid T. The underlying value will not be modified through the pointer and can 206*bb4ee6a4SAndroid Build Coastguard Worker // only be accessed through these returned references. 207*bb4ee6a4SAndroid Build Coastguard Worker unsafe { &*self.token_info } 208*bb4ee6a4SAndroid Build Coastguard Worker } 209*bb4ee6a4SAndroid Build Coastguard Worker } 210*bb4ee6a4SAndroid Build Coastguard Worker 211*bb4ee6a4SAndroid Build Coastguard Worker impl<T> AsMut<T> for TokenInformation<T> { as_mut(&mut self) -> &mut T212*bb4ee6a4SAndroid Build Coastguard Worker fn as_mut(&mut self) -> &mut T { 213*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: The underlying pointer is guaranteed to be properly aligned, dereferenceable, and 214*bb4ee6a4SAndroid Build Coastguard Worker // point to a valid T. The underlying value will not be modified through the pointer and can 215*bb4ee6a4SAndroid Build Coastguard Worker // only be accessed through these returned references. 216*bb4ee6a4SAndroid Build Coastguard Worker unsafe { &mut *self.token_info } 217*bb4ee6a4SAndroid Build Coastguard Worker } 218*bb4ee6a4SAndroid Build Coastguard Worker } 219*bb4ee6a4SAndroid Build Coastguard Worker 220*bb4ee6a4SAndroid Build Coastguard Worker impl<T> Drop for TokenInformation<T> { drop(&mut self)221*bb4ee6a4SAndroid Build Coastguard Worker fn drop(&mut self) { 222*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: We ensure the pointer is valid in the constructor, and we are using the same 223*bb4ee6a4SAndroid Build Coastguard Worker // layout struct as during the allocation. 224*bb4ee6a4SAndroid Build Coastguard Worker unsafe { dealloc(self.token_info as *mut u8, self.layout) } 225*bb4ee6a4SAndroid Build Coastguard Worker } 226*bb4ee6a4SAndroid Build Coastguard Worker } 227*bb4ee6a4SAndroid Build Coastguard Worker 228*bb4ee6a4SAndroid Build Coastguard Worker pub struct Token { 229*bb4ee6a4SAndroid Build Coastguard Worker token: RawHandle, 230*bb4ee6a4SAndroid Build Coastguard Worker } 231*bb4ee6a4SAndroid Build Coastguard Worker 232*bb4ee6a4SAndroid Build Coastguard Worker impl Token { 233*bb4ee6a4SAndroid Build Coastguard Worker /// Open the current process's token. new_for_process() -> io::Result<Self>234*bb4ee6a4SAndroid Build Coastguard Worker pub fn new_for_process() -> io::Result<Self> { 235*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: GetCurrentProcess is an alias for -1. 236*bb4ee6a4SAndroid Build Coastguard Worker Self::from_process(unsafe { GetCurrentProcess() }) 237*bb4ee6a4SAndroid Build Coastguard Worker } 238*bb4ee6a4SAndroid Build Coastguard Worker 239*bb4ee6a4SAndroid Build Coastguard Worker /// Open the token of a process. from_process(proc_handle: RawHandle) -> io::Result<Self>240*bb4ee6a4SAndroid Build Coastguard Worker pub fn from_process(proc_handle: RawHandle) -> io::Result<Self> { 241*bb4ee6a4SAndroid Build Coastguard Worker let mut token: RawHandle = ptr::null_mut(); 242*bb4ee6a4SAndroid Build Coastguard Worker 243*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: Token is valid. 244*bb4ee6a4SAndroid Build Coastguard Worker if unsafe { 245*bb4ee6a4SAndroid Build Coastguard Worker OpenProcessToken( 246*bb4ee6a4SAndroid Build Coastguard Worker /* ProcessHandle= */ proc_handle, 247*bb4ee6a4SAndroid Build Coastguard Worker /* DesiredAccess= */ TOKEN_ALL_ACCESS, 248*bb4ee6a4SAndroid Build Coastguard Worker /* TokenHandle= */ &mut token, 249*bb4ee6a4SAndroid Build Coastguard Worker ) == 0 250*bb4ee6a4SAndroid Build Coastguard Worker } { 251*bb4ee6a4SAndroid Build Coastguard Worker return Err(io::Error::last_os_error()); 252*bb4ee6a4SAndroid Build Coastguard Worker } 253*bb4ee6a4SAndroid Build Coastguard Worker Ok(Token { token }) 254*bb4ee6a4SAndroid Build Coastguard Worker } 255*bb4ee6a4SAndroid Build Coastguard Worker 256*bb4ee6a4SAndroid Build Coastguard Worker /// Open the token of a thread. from_thread(thread_handle: RawHandle) -> io::Result<Self>257*bb4ee6a4SAndroid Build Coastguard Worker pub fn from_thread(thread_handle: RawHandle) -> io::Result<Self> { 258*bb4ee6a4SAndroid Build Coastguard Worker let mut token: RawHandle = ptr::null_mut(); 259*bb4ee6a4SAndroid Build Coastguard Worker 260*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: Token is valid. We use OpenAsSelf to ensure the token access is measured 261*bb4ee6a4SAndroid Build Coastguard Worker // using the caller's non-impersonated identity. 262*bb4ee6a4SAndroid Build Coastguard Worker if unsafe { 263*bb4ee6a4SAndroid Build Coastguard Worker OpenThreadToken( 264*bb4ee6a4SAndroid Build Coastguard Worker thread_handle, 265*bb4ee6a4SAndroid Build Coastguard Worker TOKEN_ALL_ACCESS, 266*bb4ee6a4SAndroid Build Coastguard Worker /* OpenAsSelf= */ TRUE, 267*bb4ee6a4SAndroid Build Coastguard Worker &mut token, 268*bb4ee6a4SAndroid Build Coastguard Worker ) == 0 269*bb4ee6a4SAndroid Build Coastguard Worker } { 270*bb4ee6a4SAndroid Build Coastguard Worker return Err(io::Error::last_os_error()); 271*bb4ee6a4SAndroid Build Coastguard Worker } 272*bb4ee6a4SAndroid Build Coastguard Worker Ok(Token { token }) 273*bb4ee6a4SAndroid Build Coastguard Worker } 274*bb4ee6a4SAndroid Build Coastguard Worker get(&mut self) -> RawHandle275*bb4ee6a4SAndroid Build Coastguard Worker fn get(&mut self) -> RawHandle { 276*bb4ee6a4SAndroid Build Coastguard Worker self.token 277*bb4ee6a4SAndroid Build Coastguard Worker } 278*bb4ee6a4SAndroid Build Coastguard Worker } 279*bb4ee6a4SAndroid Build Coastguard Worker 280*bb4ee6a4SAndroid Build Coastguard Worker impl Drop for Token { drop(&mut self)281*bb4ee6a4SAndroid Build Coastguard Worker fn drop(&mut self) { 282*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: Token is valid, but the call should be safe regardless. 283*bb4ee6a4SAndroid Build Coastguard Worker unsafe { 284*bb4ee6a4SAndroid Build Coastguard Worker CloseHandle(self.token); 285*bb4ee6a4SAndroid Build Coastguard Worker } 286*bb4ee6a4SAndroid Build Coastguard Worker } 287*bb4ee6a4SAndroid Build Coastguard Worker } 288*bb4ee6a4SAndroid Build Coastguard Worker 289*bb4ee6a4SAndroid Build Coastguard Worker pub trait SecurityDescriptor { security_descriptor(&self) -> *const SECURITY_DESCRIPTOR290*bb4ee6a4SAndroid Build Coastguard Worker fn security_descriptor(&self) -> *const SECURITY_DESCRIPTOR; 291*bb4ee6a4SAndroid Build Coastguard Worker } 292*bb4ee6a4SAndroid Build Coastguard Worker 293*bb4ee6a4SAndroid Build Coastguard Worker pub struct AbsoluteSecurityDescriptor { 294*bb4ee6a4SAndroid Build Coastguard Worker descriptor: SECURITY_DESCRIPTOR, 295*bb4ee6a4SAndroid Build Coastguard Worker acl: *mut ACL, 296*bb4ee6a4SAndroid Build Coastguard Worker } 297*bb4ee6a4SAndroid Build Coastguard Worker 298*bb4ee6a4SAndroid Build Coastguard Worker impl AbsoluteSecurityDescriptor { 299*bb4ee6a4SAndroid Build Coastguard Worker /// Creates a `SECURITY_DESCRIPTOR` struct which gives full access rights 300*bb4ee6a4SAndroid Build Coastguard Worker /// (`GENERIC_ALL`) to only the current user. new() -> io::Result<AbsoluteSecurityDescriptor>301*bb4ee6a4SAndroid Build Coastguard Worker fn new() -> io::Result<AbsoluteSecurityDescriptor> { 302*bb4ee6a4SAndroid Build Coastguard Worker let token = Token::new_for_process()?; 303*bb4ee6a4SAndroid Build Coastguard Worker let token_user = TokenInformation::<TOKEN_USER>::new(token)?; 304*bb4ee6a4SAndroid Build Coastguard Worker let sid = token_user.as_ref().User.Sid; 305*bb4ee6a4SAndroid Build Coastguard Worker 306*bb4ee6a4SAndroid Build Coastguard Worker let mut ea = EXPLICIT_ACCESS_A { 307*bb4ee6a4SAndroid Build Coastguard Worker grfAccessPermissions: GENERIC_ALL, 308*bb4ee6a4SAndroid Build Coastguard Worker grfAccessMode: SET_ACCESS, 309*bb4ee6a4SAndroid Build Coastguard Worker grfInheritance: NO_INHERITANCE, 310*bb4ee6a4SAndroid Build Coastguard Worker Trustee: TRUSTEE_A { 311*bb4ee6a4SAndroid Build Coastguard Worker TrusteeForm: TRUSTEE_IS_SID, 312*bb4ee6a4SAndroid Build Coastguard Worker TrusteeType: TRUSTEE_IS_USER, 313*bb4ee6a4SAndroid Build Coastguard Worker ptstrName: sid as *mut i8, 314*bb4ee6a4SAndroid Build Coastguard Worker pMultipleTrustee: ptr::null_mut(), 315*bb4ee6a4SAndroid Build Coastguard Worker MultipleTrusteeOperation: NO_MULTIPLE_TRUSTEE, 316*bb4ee6a4SAndroid Build Coastguard Worker }, 317*bb4ee6a4SAndroid Build Coastguard Worker }; 318*bb4ee6a4SAndroid Build Coastguard Worker 319*bb4ee6a4SAndroid Build Coastguard Worker let mut security_descriptor: std::mem::MaybeUninit<AbsoluteSecurityDescriptor> = 320*bb4ee6a4SAndroid Build Coastguard Worker std::mem::MaybeUninit::uninit(); 321*bb4ee6a4SAndroid Build Coastguard Worker 322*bb4ee6a4SAndroid Build Coastguard Worker let ptr = security_descriptor.as_mut_ptr(); 323*bb4ee6a4SAndroid Build Coastguard Worker 324*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: security_descriptor is valid but uninitialized, and 325*bb4ee6a4SAndroid Build Coastguard Worker // InitializeSecurityDescriptor will initialize it. 326*bb4ee6a4SAndroid Build Coastguard Worker if unsafe { 327*bb4ee6a4SAndroid Build Coastguard Worker InitializeSecurityDescriptor( 328*bb4ee6a4SAndroid Build Coastguard Worker /* pSecurityDescriptor= */ 329*bb4ee6a4SAndroid Build Coastguard Worker ptr::addr_of_mut!((*ptr).descriptor) as PSECURITY_DESCRIPTOR, 330*bb4ee6a4SAndroid Build Coastguard Worker /* dwRevision= */ SECURITY_DESCRIPTOR_REVISION, 331*bb4ee6a4SAndroid Build Coastguard Worker ) == 0 332*bb4ee6a4SAndroid Build Coastguard Worker } { 333*bb4ee6a4SAndroid Build Coastguard Worker return Err(io::Error::last_os_error()); 334*bb4ee6a4SAndroid Build Coastguard Worker } 335*bb4ee6a4SAndroid Build Coastguard Worker 336*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: ea and acl are valid and OldAcl is allowed to be null. 337*bb4ee6a4SAndroid Build Coastguard Worker if unsafe { 338*bb4ee6a4SAndroid Build Coastguard Worker SetEntriesInAclA( 339*bb4ee6a4SAndroid Build Coastguard Worker /* cCountOfExplicitEntries= */ 1, 340*bb4ee6a4SAndroid Build Coastguard Worker /* pListOfExplicitEntries= */ &mut ea as PEXPLICIT_ACCESSA, 341*bb4ee6a4SAndroid Build Coastguard Worker /* OldAcl= */ ptr::null_mut(), 342*bb4ee6a4SAndroid Build Coastguard Worker /* NewAcl= */ 343*bb4ee6a4SAndroid Build Coastguard Worker ptr::addr_of_mut!((*ptr).acl) as *mut PACL, 344*bb4ee6a4SAndroid Build Coastguard Worker ) 345*bb4ee6a4SAndroid Build Coastguard Worker } != ERROR_SUCCESS 346*bb4ee6a4SAndroid Build Coastguard Worker { 347*bb4ee6a4SAndroid Build Coastguard Worker return Err(io::Error::last_os_error()); 348*bb4ee6a4SAndroid Build Coastguard Worker } 349*bb4ee6a4SAndroid Build Coastguard Worker 350*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: security_descriptor is valid and initialized after 351*bb4ee6a4SAndroid Build Coastguard Worker // InitializeSecurityDescriptor() and SetEntriesInAclA(). 352*bb4ee6a4SAndroid Build Coastguard Worker let mut security_descriptor = unsafe { security_descriptor.assume_init() }; 353*bb4ee6a4SAndroid Build Coastguard Worker let sd = &mut security_descriptor.descriptor as *mut SECURITY_DESCRIPTOR; 354*bb4ee6a4SAndroid Build Coastguard Worker 355*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: The descriptor is valid, and acl is valid after SetEntriesInAclA() 356*bb4ee6a4SAndroid Build Coastguard Worker if unsafe { 357*bb4ee6a4SAndroid Build Coastguard Worker SetSecurityDescriptorDacl( 358*bb4ee6a4SAndroid Build Coastguard Worker /* pSecurityDescriptor= */ sd as PSECURITY_DESCRIPTOR, 359*bb4ee6a4SAndroid Build Coastguard Worker /* bDaclPresent= */ TRUE, 360*bb4ee6a4SAndroid Build Coastguard Worker /* pDacl= */ security_descriptor.acl, 361*bb4ee6a4SAndroid Build Coastguard Worker /* bDaclDefaulted= */ FALSE, 362*bb4ee6a4SAndroid Build Coastguard Worker ) == 0 363*bb4ee6a4SAndroid Build Coastguard Worker } { 364*bb4ee6a4SAndroid Build Coastguard Worker return Err(io::Error::last_os_error()); 365*bb4ee6a4SAndroid Build Coastguard Worker } 366*bb4ee6a4SAndroid Build Coastguard Worker 367*bb4ee6a4SAndroid Build Coastguard Worker Ok(security_descriptor) 368*bb4ee6a4SAndroid Build Coastguard Worker } 369*bb4ee6a4SAndroid Build Coastguard Worker } 370*bb4ee6a4SAndroid Build Coastguard Worker 371*bb4ee6a4SAndroid Build Coastguard Worker impl SecurityDescriptor for AbsoluteSecurityDescriptor { security_descriptor(&self) -> *const SECURITY_DESCRIPTOR372*bb4ee6a4SAndroid Build Coastguard Worker fn security_descriptor(&self) -> *const SECURITY_DESCRIPTOR { 373*bb4ee6a4SAndroid Build Coastguard Worker &self.descriptor as *const SECURITY_DESCRIPTOR 374*bb4ee6a4SAndroid Build Coastguard Worker } 375*bb4ee6a4SAndroid Build Coastguard Worker } 376*bb4ee6a4SAndroid Build Coastguard Worker 377*bb4ee6a4SAndroid Build Coastguard Worker impl Drop for AbsoluteSecurityDescriptor { drop(&mut self)378*bb4ee6a4SAndroid Build Coastguard Worker fn drop(&mut self) { 379*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: We guarantee that on creation acl is initialized to a pointer that can be freed. 380*bb4ee6a4SAndroid Build Coastguard Worker unsafe { LocalFree(self.acl as HLOCAL) }; 381*bb4ee6a4SAndroid Build Coastguard Worker } 382*bb4ee6a4SAndroid Build Coastguard Worker } 383*bb4ee6a4SAndroid Build Coastguard Worker 384*bb4ee6a4SAndroid Build Coastguard Worker pub struct SelfRelativeSecurityDescriptor { 385*bb4ee6a4SAndroid Build Coastguard Worker descriptor: *mut SECURITY_DESCRIPTOR, 386*bb4ee6a4SAndroid Build Coastguard Worker layout: Layout, 387*bb4ee6a4SAndroid Build Coastguard Worker } 388*bb4ee6a4SAndroid Build Coastguard Worker 389*bb4ee6a4SAndroid Build Coastguard Worker impl Drop for SelfRelativeSecurityDescriptor { drop(&mut self)390*bb4ee6a4SAndroid Build Coastguard Worker fn drop(&mut self) { 391*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: We own self.descriptor and guarantee it is a valid pointer. 392*bb4ee6a4SAndroid Build Coastguard Worker unsafe { dealloc(self.descriptor as *mut u8, self.layout) } 393*bb4ee6a4SAndroid Build Coastguard Worker } 394*bb4ee6a4SAndroid Build Coastguard Worker } 395*bb4ee6a4SAndroid Build Coastguard Worker 396*bb4ee6a4SAndroid Build Coastguard Worker impl Clone for SelfRelativeSecurityDescriptor { clone(&self) -> Self397*bb4ee6a4SAndroid Build Coastguard Worker fn clone(&self) -> Self { 398*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: We know that the layout's size is non-zero. 399*bb4ee6a4SAndroid Build Coastguard Worker let descriptor = unsafe { alloc_zeroed(self.layout) } as *mut SECURITY_DESCRIPTOR; 400*bb4ee6a4SAndroid Build Coastguard Worker if descriptor.is_null() { 401*bb4ee6a4SAndroid Build Coastguard Worker handle_alloc_error(self.layout); 402*bb4ee6a4SAndroid Build Coastguard Worker } 403*bb4ee6a4SAndroid Build Coastguard Worker let sd = SelfRelativeSecurityDescriptor { 404*bb4ee6a4SAndroid Build Coastguard Worker descriptor, 405*bb4ee6a4SAndroid Build Coastguard Worker layout: self.layout, 406*bb4ee6a4SAndroid Build Coastguard Worker }; 407*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: 408*bb4ee6a4SAndroid Build Coastguard Worker // * `src` is at least `count` bytes, as it was allocated using the above layout. 409*bb4ee6a4SAndroid Build Coastguard Worker // * `dst` is at least `count` bytes, as we just allocated it using the above layout. 410*bb4ee6a4SAndroid Build Coastguard Worker // * `src` and `dst` are aligned according to the layout, and we are copying byte-wise. 411*bb4ee6a4SAndroid Build Coastguard Worker // * `src` and `dst` do not overlap, as we just allocated new memory for `dst`. 412*bb4ee6a4SAndroid Build Coastguard Worker unsafe { 413*bb4ee6a4SAndroid Build Coastguard Worker std::ptr::copy_nonoverlapping::<u8>( 414*bb4ee6a4SAndroid Build Coastguard Worker /* src= */ self.descriptor as *const u8, 415*bb4ee6a4SAndroid Build Coastguard Worker /* dst= */ sd.descriptor as *mut u8, 416*bb4ee6a4SAndroid Build Coastguard Worker /* count= */ self.layout.size(), 417*bb4ee6a4SAndroid Build Coastguard Worker ) 418*bb4ee6a4SAndroid Build Coastguard Worker }; 419*bb4ee6a4SAndroid Build Coastguard Worker sd 420*bb4ee6a4SAndroid Build Coastguard Worker } 421*bb4ee6a4SAndroid Build Coastguard Worker } 422*bb4ee6a4SAndroid Build Coastguard Worker 423*bb4ee6a4SAndroid Build Coastguard Worker impl TryFrom<AbsoluteSecurityDescriptor> for SelfRelativeSecurityDescriptor { 424*bb4ee6a4SAndroid Build Coastguard Worker type Error = io::Error; 425*bb4ee6a4SAndroid Build Coastguard Worker try_from(sd: AbsoluteSecurityDescriptor) -> io::Result<Self>426*bb4ee6a4SAndroid Build Coastguard Worker fn try_from(sd: AbsoluteSecurityDescriptor) -> io::Result<Self> { 427*bb4ee6a4SAndroid Build Coastguard Worker let mut size: u32 = 0; 428*bb4ee6a4SAndroid Build Coastguard Worker let descriptor = &sd.descriptor as *const SECURITY_DESCRIPTOR; 429*bb4ee6a4SAndroid Build Coastguard Worker 430*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: Descriptor and size are valid, and pSelfRelativeSD is optional and allowed to be 431*bb4ee6a4SAndroid Build Coastguard Worker // null. 432*bb4ee6a4SAndroid Build Coastguard Worker if unsafe { 433*bb4ee6a4SAndroid Build Coastguard Worker MakeSelfRelativeSD( 434*bb4ee6a4SAndroid Build Coastguard Worker /* pAbsoluteSD= */ descriptor as PSECURITY_DESCRIPTOR, 435*bb4ee6a4SAndroid Build Coastguard Worker /* pSelfRelativeSD= */ ptr::null_mut(), 436*bb4ee6a4SAndroid Build Coastguard Worker /* lpdwBufferLength= */ &mut size as LPDWORD, 437*bb4ee6a4SAndroid Build Coastguard Worker ) 438*bb4ee6a4SAndroid Build Coastguard Worker } == 0 439*bb4ee6a4SAndroid Build Coastguard Worker { 440*bb4ee6a4SAndroid Build Coastguard Worker const INSUFFICIENT_BUFFER: i32 = ERROR_INSUFFICIENT_BUFFER as i32; 441*bb4ee6a4SAndroid Build Coastguard Worker match io::Error::last_os_error().raw_os_error() { 442*bb4ee6a4SAndroid Build Coastguard Worker Some(INSUFFICIENT_BUFFER) => { 443*bb4ee6a4SAndroid Build Coastguard Worker // Despite returning failure, the function will fill in the 444*bb4ee6a4SAndroid Build Coastguard Worker // expected buffer length into the lpdwBufferLength parameter. 445*bb4ee6a4SAndroid Build Coastguard Worker // It may fail in other ways (e.g. if an invalid pAbsoluteSD 446*bb4ee6a4SAndroid Build Coastguard Worker // is provided), so we check that we receive the expected 447*bb4ee6a4SAndroid Build Coastguard Worker // error code before assuming that we received a valid 448*bb4ee6a4SAndroid Build Coastguard Worker // lpdwBufferLength. In this case, we can ignore the error. 449*bb4ee6a4SAndroid Build Coastguard Worker } 450*bb4ee6a4SAndroid Build Coastguard Worker _ => return Err(io::Error::last_os_error()), 451*bb4ee6a4SAndroid Build Coastguard Worker } 452*bb4ee6a4SAndroid Build Coastguard Worker } 453*bb4ee6a4SAndroid Build Coastguard Worker // size must be > 0. 0-sized layouts break alloc()'s assumptions. 454*bb4ee6a4SAndroid Build Coastguard Worker assert!(size > 0, "Unable to get size of self-relative SD"); 455*bb4ee6a4SAndroid Build Coastguard Worker 456*bb4ee6a4SAndroid Build Coastguard Worker // Since we don't statically know the full size of the struct, we 457*bb4ee6a4SAndroid Build Coastguard Worker // allocate memory for it based on the previous call, aligned to pointer 458*bb4ee6a4SAndroid Build Coastguard Worker // size. 459*bb4ee6a4SAndroid Build Coastguard Worker let layout = Layout::from_size_align(size as usize, size_of::<LPVOID>()) 460*bb4ee6a4SAndroid Build Coastguard Worker .expect("Failed to create layout"); 461*bb4ee6a4SAndroid Build Coastguard Worker assert!(layout.size() > 0, "Failed to create valid layout"); 462*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: We assert that layout's size is non-zero. 463*bb4ee6a4SAndroid Build Coastguard Worker let self_relative_sd = unsafe { alloc_zeroed(layout) } as *mut SECURITY_DESCRIPTOR; 464*bb4ee6a4SAndroid Build Coastguard Worker if self_relative_sd.is_null() { 465*bb4ee6a4SAndroid Build Coastguard Worker handle_alloc_error(layout); 466*bb4ee6a4SAndroid Build Coastguard Worker } 467*bb4ee6a4SAndroid Build Coastguard Worker 468*bb4ee6a4SAndroid Build Coastguard Worker let self_relative_sd = SelfRelativeSecurityDescriptor { 469*bb4ee6a4SAndroid Build Coastguard Worker descriptor: self_relative_sd, 470*bb4ee6a4SAndroid Build Coastguard Worker layout, 471*bb4ee6a4SAndroid Build Coastguard Worker }; 472*bb4ee6a4SAndroid Build Coastguard Worker 473*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: Descriptor is valid, the newly allocated self_relative_sd descriptor is valid, 474*bb4ee6a4SAndroid Build Coastguard Worker // and size is valid. 475*bb4ee6a4SAndroid Build Coastguard Worker if unsafe { 476*bb4ee6a4SAndroid Build Coastguard Worker MakeSelfRelativeSD( 477*bb4ee6a4SAndroid Build Coastguard Worker /* pAbsoluteSD= */ descriptor as PSECURITY_DESCRIPTOR, 478*bb4ee6a4SAndroid Build Coastguard Worker /* pSelfRelativeSD= */ self_relative_sd.descriptor as PSECURITY_DESCRIPTOR, 479*bb4ee6a4SAndroid Build Coastguard Worker /* lpdwBufferLength= */ &mut size as LPDWORD, 480*bb4ee6a4SAndroid Build Coastguard Worker ) 481*bb4ee6a4SAndroid Build Coastguard Worker } == 0 482*bb4ee6a4SAndroid Build Coastguard Worker { 483*bb4ee6a4SAndroid Build Coastguard Worker return Err(io::Error::last_os_error()); 484*bb4ee6a4SAndroid Build Coastguard Worker } 485*bb4ee6a4SAndroid Build Coastguard Worker 486*bb4ee6a4SAndroid Build Coastguard Worker Ok(self_relative_sd) 487*bb4ee6a4SAndroid Build Coastguard Worker } 488*bb4ee6a4SAndroid Build Coastguard Worker } 489*bb4ee6a4SAndroid Build Coastguard Worker 490*bb4ee6a4SAndroid Build Coastguard Worker impl SelfRelativeSecurityDescriptor { 491*bb4ee6a4SAndroid Build Coastguard Worker /// Creates a `SECURITY_DESCRIPTOR` struct which gives full access rights 492*bb4ee6a4SAndroid Build Coastguard Worker /// (`GENERIC_ALL`) to only the current user. new() -> io::Result<Self>493*bb4ee6a4SAndroid Build Coastguard Worker fn new() -> io::Result<Self> { 494*bb4ee6a4SAndroid Build Coastguard Worker AbsoluteSecurityDescriptor::new()?.try_into() 495*bb4ee6a4SAndroid Build Coastguard Worker } 496*bb4ee6a4SAndroid Build Coastguard Worker 497*bb4ee6a4SAndroid Build Coastguard Worker /// Gets a copy of a singleton `SelfRelativeSecurityDescriptor`. get_singleton() -> SelfRelativeSecurityDescriptor498*bb4ee6a4SAndroid Build Coastguard Worker pub fn get_singleton() -> SelfRelativeSecurityDescriptor { 499*bb4ee6a4SAndroid Build Coastguard Worker static DEFAULT_SECURITY_DESCRIPTOR: OnceCell<SelfRelativeSecurityDescriptor> = 500*bb4ee6a4SAndroid Build Coastguard Worker OnceCell::new(); 501*bb4ee6a4SAndroid Build Coastguard Worker DEFAULT_SECURITY_DESCRIPTOR 502*bb4ee6a4SAndroid Build Coastguard Worker .get_or_init(|| { 503*bb4ee6a4SAndroid Build Coastguard Worker SelfRelativeSecurityDescriptor::new().expect("Failed to create security descriptor") 504*bb4ee6a4SAndroid Build Coastguard Worker }) 505*bb4ee6a4SAndroid Build Coastguard Worker .clone() 506*bb4ee6a4SAndroid Build Coastguard Worker } 507*bb4ee6a4SAndroid Build Coastguard Worker } 508*bb4ee6a4SAndroid Build Coastguard Worker 509*bb4ee6a4SAndroid Build Coastguard Worker impl SecurityDescriptor for SelfRelativeSecurityDescriptor { security_descriptor(&self) -> *const SECURITY_DESCRIPTOR510*bb4ee6a4SAndroid Build Coastguard Worker fn security_descriptor(&self) -> *const SECURITY_DESCRIPTOR { 511*bb4ee6a4SAndroid Build Coastguard Worker self.descriptor 512*bb4ee6a4SAndroid Build Coastguard Worker } 513*bb4ee6a4SAndroid Build Coastguard Worker } 514*bb4ee6a4SAndroid Build Coastguard Worker 515*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: The descriptor and ACLs are treated as immutable by consuming functions and can be safely 516*bb4ee6a4SAndroid Build Coastguard Worker // shared between threads. 517*bb4ee6a4SAndroid Build Coastguard Worker unsafe impl Send for SelfRelativeSecurityDescriptor {} 518*bb4ee6a4SAndroid Build Coastguard Worker 519*bb4ee6a4SAndroid Build Coastguard Worker //SAFETY: The descriptor and ACLs are treated as immutable by consuming functions. 520*bb4ee6a4SAndroid Build Coastguard Worker unsafe impl Sync for SelfRelativeSecurityDescriptor {} 521