@@ -212,10 +212,6 @@ mod linux {
212212 }
213213
214214 impl MemoryReader for ReadableProcessMemory {
215- /// Reads a slice `\[offset..(offset+length)\]` of the opened process' memory
216- /// and returns it as a [`Vec<u8>`]. `offset` is considered as an absolute offset
217- /// in the process' address space. If the slice falls outside the memory's address space,
218- /// the returned buffer will be truncated.
219215 fn read_chunk ( & mut self , offset : u64 , length : u64 ) -> std:: io:: Result < Vec < u8 > > {
220216 self . mem_file . seek ( SeekFrom :: Start ( offset) ) ?;
221217 let mut buf = Vec :: new ( ) ;
@@ -267,12 +263,12 @@ mod linux {
267263 }
268264
269265 #[ cfg( test) ]
270- mod test {
266+ mod tests {
271267 use super :: * ;
272268
273269 #[ test]
274270 fn region_iter_detects_mmap ( ) {
275- // `mmap` a file and check that the mapping is detected among those returned by
271+ // `mmap` a file and check that the mappinsg is detected among those returned by
276272 // `MappedRegionIter`.
277273 use std:: io:: Write as _;
278274 use std:: os:: unix:: fs:: MetadataExt ;
@@ -339,7 +335,7 @@ mod windows {
339335
340336 impl ProcessHandle {
341337 fn open ( pid : u32 ) -> std:: io:: Result < Self > {
342- // Open a handle to the process with all access rights
338+ // SAFETY: the returned handle will be closed by the `drop` impl.
343339 let handle: HANDLE = unsafe { OpenProcess ( PROCESS_ALL_ACCESS , 0 , pid) } ;
344340 if handle. is_null ( ) {
345341 Err ( std:: io:: Error :: last_os_error ( ) )
@@ -351,6 +347,8 @@ mod windows {
351347
352348 impl Drop for ProcessHandle {
353349 fn drop ( & mut self ) {
350+ // SAFETY: since this struct has no `Clone` or `Copy` impl,
351+ // this handle will not be used again after the struct is dropped.
354352 unsafe { CloseHandle ( self . 0 ) } ;
355353 }
356354 }
@@ -390,16 +388,12 @@ mod windows {
390388 mem_info. AllocationProtect
391389 } ;
392390
393- let execute = flags & EXECUTE_FLAGS != 0 ;
394- let write = flags & WRITE_FLAGS != 0 ;
395- // The only flag which disables write access is PAGE_NOACCESS
396- let read = flags & PAGE_NOACCESS == 0 ;
397- let private = mem_info. Type == MEM_PRIVATE ;
398391 Permissions {
399- read,
400- write,
401- execute,
402- private,
392+ // The only flag which disables read access is PAGE_NOACCESS
393+ read : flags & PAGE_NOACCESS == 0 ,
394+ write : flags & WRITE_FLAGS != 0 ,
395+ execute : flags & EXECUTE_FLAGS != 0 ,
396+ private : mem_info. Type == MEM_PRIVATE ,
403397 shared : false ,
404398 }
405399 }
@@ -412,6 +406,8 @@ mod windows {
412406 use std:: os:: windows:: ffi:: OsStringExt ;
413407
414408 let mut buf = [ 0u16 ; ( MAX_PATH + 1 ) as usize ] ;
409+ // SAFETY: `GetMappedFileNameW` will only write up to `nSize` (last argument)
410+ // characters in `buf` (null-terminator included). Therefore there can be no buffer overflow.
415411 let len = unsafe { GetMappedFileNameW ( process. 0 , addr, buf. as_mut_ptr ( ) , buf. len ( ) as u32 ) }
416412 as usize ;
417413 // A return value of 0 indicates an error, and nSize indicates that the path was
@@ -429,14 +425,17 @@ mod windows {
429425 let mem_info: MEMORY_BASIC_INFORMATION = {
430426 let mut mem: std:: mem:: MaybeUninit < MEMORY_BASIC_INFORMATION > =
431427 MaybeUninit :: zeroed ( ) ;
432- if unsafe {
428+ // SAFETY: `VirtualQueryEx` will only write up to `dwLength` (last argument)
429+ // bytes in `mem`.
430+ let status = unsafe {
433431 VirtualQueryEx (
434432 self . process . 0 ,
435433 self . cur_addr ,
436434 mem. as_mut_ptr ( ) ,
437435 std:: mem:: size_of :: < MEMORY_BASIC_INFORMATION > ( ) ,
438- ) == 0
439- } {
436+ )
437+ } ;
438+ if status == 0 {
440439 let err = std:: io:: Error :: last_os_error ( ) ;
441440 // InvalidInput is returned when the given address
442441 // falls beyond the last page accessible by the process,
@@ -446,6 +445,8 @@ mod windows {
446445 }
447446 break Some ( Err ( err) ) ;
448447 }
448+ // SAFETY: We just checked that the call to `VirtualQueryEx`
449+ // has succeeded, so we can safely assume that `mem` was initialized.
449450 unsafe { mem. assume_init ( ) }
450451 } ;
451452
@@ -484,23 +485,21 @@ mod windows {
484485 }
485486
486487 impl MemoryReader for ReadableProcessMemory {
487- /// Reads a slice `\[offset..(offset+length)\]` of the opened process' memory
488- /// and returns it as a [`Vec<u8>`]. `offset` is considered as an absolute offset
489- /// in the process' address space. If the slice falls outside the memory's address space,
490- /// the returned buffer will be truncated.
491488 fn read_chunk ( & mut self , offset : u64 , length : u64 ) -> std:: io:: Result < Vec < u8 > > {
492489 let mut buf = vec ! [ 0 ; length as usize ] ;
493490 let mut bytes_read = 0 ;
494- if unsafe {
491+ // SAFETY: `ReadProcessMemory` will write at most `nSize` (second to last argument) bytes
492+ // in `buf`, so the bounded length prevents a buffer overflow.
493+ let status = unsafe {
495494 ReadProcessMemory (
496495 self . process . 0 ,
497496 std:: ptr:: without_provenance_mut ( offset as usize ) ,
498497 buf. as_mut_ptr ( ) . cast ( ) ,
499498 buf. len ( ) ,
500499 & mut bytes_read,
501500 )
502- } == 0
503- {
501+ } ;
502+ if status == 0 {
504503 return Err ( std:: io:: Error :: last_os_error ( ) ) ;
505504 }
506505 buf. truncate ( bytes_read) ;
@@ -509,7 +508,7 @@ mod windows {
509508 }
510509
511510 #[ cfg( test) ]
512- mod test {
511+ mod tests {
513512 use super :: * ;
514513
515514 #[ test]
@@ -529,7 +528,8 @@ mod windows {
529528 let meta = file. metadata ( ) . unwrap ( ) ;
530529 let length = meta. len ( ) as usize ;
531530
532- // Create a file mapping object for the file
531+ // SAFETY: the returned mapping will be dropped
532+ // by `OwnedHandle`'s `drop` impl.
533533 let mapping = unsafe {
534534 CreateFileMappingW (
535535 file. as_raw_handle ( ) ,
@@ -542,9 +542,11 @@ mod windows {
542542 } ;
543543
544544 if mapping. is_null ( ) {
545- panic ! ( "Could not create file mapping" ) ;
545+ panic ! ( "could not create file mapping" ) ;
546546 }
547547
548+ // SAFETY: we just cheched that the mapping was created succesfully.
549+ // The raw handle was also not copied to another variable in the meantime
548550 let mapping = unsafe { OwnedHandle :: from_raw_handle ( mapping) } ;
549551
550552 /// RAII wrapper around a `mmap`ed pointer that will `munmap` on drop.
@@ -554,6 +556,7 @@ mod windows {
554556
555557 impl Drop for MappedView {
556558 fn drop ( & mut self ) {
559+ // SAFETY: we only need `unsafe` to call the FFI function here.
557560 unsafe {
558561 UnmapViewOfFile ( self . addr ) ;
559562 }
@@ -563,6 +566,8 @@ mod windows {
563566 // Map the view and test the results.
564567
565568 let view = unsafe {
569+ // SAFETY: the returned mapping will be unmapped by `MappedView`'s `drop`
570+ // impl. We check right away if the returned handle is valid.
566571 let addr = MapViewOfFile (
567572 mapping. as_raw_handle ( ) , // handle to mapping object
568573 FILE_MAP_ALL_ACCESS , // read/write
@@ -575,9 +580,9 @@ mod windows {
575580 } ;
576581
577582 let regions: Vec < MappedRegion > = MappedRegionIter :: from_pid ( std:: process:: id ( ) )
578- . expect ( "Could not read memory regions of current process" )
583+ . expect ( "could not read memory regions of current process" )
579584 . collect :: < Result < _ , _ > > ( )
580- . expect ( "Reading maps" ) ;
585+ . expect ( "reading maps" ) ;
581586
582587 assert ! ( regions. into_iter( ) . any( |r| {
583588 r. address_start == view. addr. Value as u64
@@ -959,7 +964,7 @@ where
959964}
960965
961966#[ cfg( test) ]
962- mod test {
967+ mod tests {
963968 use super :: * ;
964969
965970 struct FakeProcessMemory {
@@ -989,9 +994,9 @@ mod test {
989994 fn can_read_this_process_memory ( ) {
990995 let pid = std:: process:: id ( ) ;
991996 let regions: Vec < MappedRegion > = MappedRegionIter :: from_pid ( pid)
992- . expect ( "Could not read memory regions of current process" )
997+ . expect ( "could not read memory regions of current process" )
993998 . collect :: < Result < _ , _ > > ( )
994- . expect ( "Reading maps" ) ;
999+ . expect ( "reading maps" ) ;
9951000
9961001 let mut memory = ReadableProcessMemory :: open ( pid) . expect ( "Could not open process memory" ) ;
9971002 assert ! {
0 commit comments