@@ -227,15 +227,22 @@ pub(crate) fn migrate_device(
227
227
228
228
#[ cfg( windows) ]
229
229
mod windows {
230
- use std:: { ffi:: OsStr , io, os:: windows:: ffi:: OsStrExt , path:: Path , ptr} ;
230
+ use std:: {
231
+ ffi:: OsStr ,
232
+ io,
233
+ os:: windows:: ffi:: OsStrExt ,
234
+ path:: Path ,
235
+ ptr:: { self , NonNull } ,
236
+ } ;
231
237
use talpid_types:: ErrorExt ;
232
238
use tokio:: fs;
233
239
use windows_sys:: Win32 :: {
234
- Foundation :: { LocalFree , ERROR_SUCCESS , HLOCAL , PSID } ,
240
+ Foundation :: { LocalFree , ERROR_SUCCESS , PSID } ,
235
241
Security :: {
236
242
Authorization :: { GetNamedSecurityInfoW , SE_FILE_OBJECT , SE_OBJECT_TYPE } ,
237
243
IsWellKnownSid , WinBuiltinAdministratorsSid , WinLocalSystemSid ,
238
- OWNER_SECURITY_INFORMATION , SECURITY_DESCRIPTOR , SID , WELL_KNOWN_SID_TYPE ,
244
+ OWNER_SECURITY_INFORMATION , PSECURITY_DESCRIPTOR , SECURITY_DESCRIPTOR , SID ,
245
+ WELL_KNOWN_SID_TYPE ,
239
246
} ,
240
247
} ;
241
248
@@ -355,8 +362,8 @@ mod windows {
355
362
}
356
363
357
364
struct SecurityInformation {
358
- security_descriptor : * mut SECURITY_DESCRIPTOR ,
359
- owner : PSID ,
365
+ security_descriptor : NonNull < SECURITY_DESCRIPTOR > ,
366
+ owner : Option < NonNull < SID > > ,
360
367
}
361
368
362
369
impl SecurityInformation {
@@ -375,9 +382,12 @@ mod windows {
375
382
let mut u16_path: Vec < u16 > = object_name. as_ref ( ) . encode_wide ( ) . collect ( ) ;
376
383
u16_path. push ( 0u16 ) ;
377
384
378
- let mut security_descriptor = ptr:: null_mut ( ) ;
379
- let mut owner = ptr:: null_mut ( ) ;
385
+ let mut security_descriptor: PSECURITY_DESCRIPTOR = ptr:: null_mut ( ) ;
386
+ let mut owner: PSID = ptr:: null_mut ( ) ;
380
387
388
+ // SAFETY:
389
+ // - u16_path is a null-terminated UTF-16 string
390
+ // - The *mut pointers are allowed to be null
381
391
let status = unsafe {
382
392
GetNamedSecurityInfoW (
383
393
u16_path. as_ptr ( ) ,
@@ -395,25 +405,35 @@ mod windows {
395
405
return Err ( std:: io:: Error :: from_raw_os_error ( status as i32 ) ) ;
396
406
}
397
407
408
+ let Some ( security_descriptor) = NonNull :: new ( security_descriptor) else {
409
+ return Err ( std:: io:: Error :: other ( "GetNamedSecurityInfoW returned null" ) ) ;
410
+ } ;
411
+
398
412
Ok ( SecurityInformation {
399
- security_descriptor : security_descriptor as * mut _ ,
400
- owner,
413
+ security_descriptor : security_descriptor. cast :: < SECURITY_DESCRIPTOR > ( ) ,
414
+ owner : NonNull :: new ( owner . cast :: < SID > ( ) ) ,
401
415
} )
402
416
}
403
417
404
418
pub fn owner ( & self ) -> Option < & SID > {
405
- unsafe { ( self . owner as * const SID ) . as_ref ( ) }
419
+ // SAFETY: GetNamedSecurityInfoW promises that this pointer was valid,
420
+ // and it should stay valid until we deallocate self.security_descriptor.
421
+ self . owner . map ( |ptr| unsafe { ptr. as_ref ( ) } )
406
422
}
407
423
}
408
424
409
425
impl Drop for SecurityInformation {
410
426
fn drop ( & mut self ) {
411
- unsafe { LocalFree ( self . security_descriptor as HLOCAL ) } ;
427
+ // SAFETY: GetNamedSecurityInfoW promises that this pointer was valid,
428
+ // and we do not deallocate it before this point. Since we have &mut self,
429
+ // we know that no one else has a reference to security_descriptor.
430
+ unsafe { LocalFree ( self . security_descriptor . as_ptr ( ) as PSECURITY_DESCRIPTOR ) } ;
412
431
}
413
432
}
414
433
415
434
fn is_well_known_sid ( sid : & SID , well_known_sid_type : WELL_KNOWN_SID_TYPE ) -> bool {
416
- unsafe { IsWellKnownSid ( sid as * const SID as * mut _ , well_known_sid_type) == 1 }
435
+ // SAFETY: this function doesn't take ownership of sid, and is trivially safe to call.
436
+ unsafe { IsWellKnownSid ( sid as * const SID as PSID , well_known_sid_type) == 1 }
417
437
}
418
438
}
419
439
0 commit comments