@@ -11,6 +11,19 @@ use core::ptr;
1111use core:: ptr:: NonNull ;
1212use uefi_raw:: PhysicalAddress ;
1313
14+ const fn validate_meta ( meta : MemoryMapMeta ) -> Result < usize , MemoryMapError > {
15+ if meta. desc_size < size_of :: < MemoryDescriptor > ( )
16+ || !meta
17+ . desc_size
18+ . is_multiple_of ( align_of :: < MemoryDescriptor > ( ) )
19+ || !meta. map_size . is_multiple_of ( meta. desc_size )
20+ {
21+ Err ( MemoryMapError :: InvalidSize )
22+ } else {
23+ Ok ( meta. map_size / meta. desc_size )
24+ }
25+ }
26+
1427/// Errors that may happen when constructing a [`MemoryMapRef`] or
1528/// [`MemoryMapRefMut`].
1629#[ derive( Copy , Clone , Debug ) ]
@@ -50,10 +63,11 @@ impl<'a> MemoryMapRef<'a> {
5063 if buffer. len ( ) < meta. map_size {
5164 return Err ( MemoryMapError :: InvalidSize ) ;
5265 }
66+ let len = validate_meta ( meta) ?;
5367 Ok ( Self {
5468 buf : buffer,
5569 meta,
56- len : meta . entry_count ( ) ,
70+ len,
5771 } )
5872 }
5973}
@@ -112,10 +126,11 @@ impl<'a> MemoryMapRefMut<'a> {
112126 if buffer. len ( ) < meta. map_size {
113127 return Err ( MemoryMapError :: InvalidSize ) ;
114128 }
129+ let len = validate_meta ( meta) ?;
115130 Ok ( Self {
116131 buf : buffer,
117132 meta,
118- len : meta . entry_count ( ) ,
133+ len,
119134 } )
120135 }
121136}
@@ -147,7 +162,9 @@ impl MemoryMap for MemoryMapRefMut<'_> {
147162
148163impl MemoryMapMut for MemoryMapRefMut < ' _ > {
149164 fn sort ( & mut self ) {
150- self . qsort ( 0 , self . len - 1 ) ;
165+ if self . len > 1 {
166+ self . qsort ( 0 , self . len - 1 ) ;
167+ }
151168 }
152169
153170 unsafe fn buffer_mut ( & mut self ) -> & mut [ u8 ] {
@@ -281,6 +298,12 @@ impl MemoryMapBackingMemory {
281298 let memory_map_meta = boot:: memory_map_size ( ) ;
282299 let len = Self :: safe_allocation_size_hint ( memory_map_meta) ;
283300 let ptr = boot:: allocate_pool ( memory_type, len) ?. as_ptr ( ) ;
301+ // Initialize all bytes.
302+ //
303+ // SAFETY: Pointer is valid.
304+ unsafe {
305+ ptr. write_bytes ( 0 , len) ;
306+ } ;
284307
285308 // Should be fine as UEFI always has allocations with a guaranteed
286309 // alignment of 8 bytes.
@@ -329,12 +352,14 @@ impl MemoryMapBackingMemory {
329352 /// Returns a slice to the underlying memory.
330353 #[ must_use]
331354 pub const fn as_slice ( & self ) -> & [ u8 ] {
355+ // SAFETY: Memory is valid and initialized.
332356 unsafe { self . 0 . as_ref ( ) }
333357 }
334358
335359 /// Returns a mutable slice to the underlying memory.
336360 #[ must_use]
337361 pub const fn as_mut_slice ( & mut self ) -> & mut [ u8 ] {
362+ // SAFETY: Memory is valid and initialized.
338363 unsafe { self . 0 . as_mut ( ) }
339364 }
340365}
@@ -389,7 +414,7 @@ impl MemoryMap for MemoryMapOwned {
389414 }
390415
391416 fn buffer ( & self ) -> & [ u8 ] {
392- self . buf . as_slice ( )
417+ & self . buf . as_slice ( ) [ .. self . meta . map_size ]
393418 }
394419
395420 fn entries ( & self ) -> MemoryMapIter < ' _ > {
@@ -411,7 +436,7 @@ impl MemoryMapMut for MemoryMapOwned {
411436 }
412437
413438 unsafe fn buffer_mut ( & mut self ) -> & mut [ u8 ] {
414- self . buf . as_mut_slice ( )
439+ & mut self . buf . as_mut_slice ( ) [ .. self . meta . map_size ]
415440 }
416441}
417442
@@ -490,6 +515,10 @@ mod tests {
490515 mmap. entries( ) . copied( ) . collect:: <Vec <_>>( ) . as_slice( ) ,
491516 & BASE_MMAP_UNSORTED
492517 ) ;
518+ let mut entries = mmap. entries ( ) ;
519+ assert_eq ! ( entries. len( ) , 3 ) ;
520+ assert ! ( entries. next( ) . is_some( ) ) ;
521+ assert_eq ! ( entries. len( ) , 2 ) ;
493522 assert ! ( !mmap. is_sorted( ) ) ;
494523 }
495524
@@ -510,6 +539,68 @@ mod tests {
510539 assert ! ( mmap. is_sorted( ) ) ;
511540 }
512541
542+ #[ test]
543+ fn memory_map_ref_mut_sorts_empty_map ( ) {
544+ let mut memory: [ MemoryDescriptor ; 0 ] = [ ] ;
545+ let desc_size = size_of :: < MemoryDescriptor > ( ) ;
546+ let raw = unsafe { core:: slice:: from_raw_parts_mut ( memory. as_mut_ptr ( ) . cast ( ) , 0 ) } ;
547+ let meta = MemoryMapMeta {
548+ map_size : 0 ,
549+ desc_size,
550+ map_key : Default :: default ( ) ,
551+ desc_version : MemoryDescriptor :: VERSION ,
552+ } ;
553+
554+ let mut mmap = MemoryMapRefMut :: new ( raw, meta) . unwrap ( ) ;
555+ mmap. sort ( ) ;
556+
557+ assert ! ( mmap. is_empty( ) ) ;
558+ assert ! ( mmap. is_sorted( ) ) ;
559+ }
560+
561+ #[ test]
562+ fn memory_map_ref_rejects_invalid_meta ( ) {
563+ let mut memory = [ MemoryDescriptor :: default ( ) ; 2 ] ;
564+ let raw_len = size_of_val ( & memory) ;
565+ let raw = unsafe { core:: slice:: from_raw_parts_mut ( memory. as_mut_ptr ( ) . cast ( ) , raw_len) } ;
566+ let desc_size = size_of :: < MemoryDescriptor > ( ) ;
567+ let base_meta = MemoryMapMeta {
568+ map_size : desc_size,
569+ desc_size,
570+ map_key : Default :: default ( ) ,
571+ desc_version : MemoryDescriptor :: VERSION ,
572+ } ;
573+
574+ let mut meta = base_meta;
575+ meta. desc_size = 0 ;
576+ assert ! ( matches!(
577+ MemoryMapRef :: new( raw, meta) ,
578+ Err ( MemoryMapError :: InvalidSize )
579+ ) ) ;
580+
581+ let mut meta = base_meta;
582+ meta. desc_size = desc_size - 1 ;
583+ assert ! ( matches!(
584+ MemoryMapRef :: new( raw, meta) ,
585+ Err ( MemoryMapError :: InvalidSize )
586+ ) ) ;
587+
588+ let mut meta = base_meta;
589+ meta. desc_size = desc_size + 1 ;
590+ meta. map_size = meta. desc_size ;
591+ assert ! ( matches!(
592+ MemoryMapRef :: new( raw, meta) ,
593+ Err ( MemoryMapError :: InvalidSize )
594+ ) ) ;
595+
596+ let mut meta = base_meta;
597+ meta. map_size = desc_size + 1 ;
598+ assert ! ( matches!(
599+ MemoryMapRef :: new( raw, meta) ,
600+ Err ( MemoryMapError :: InvalidSize )
601+ ) ) ;
602+ }
603+
513604 /// Basic sanity checks for the type [`MemoryMapOwned`].
514605 #[ test]
515606 fn memory_map_owned ( ) {
@@ -527,4 +618,27 @@ mod tests {
527618 mmap. sort ( ) ;
528619 assert ! ( mmap. is_sorted( ) ) ;
529620 }
621+
622+ #[ test]
623+ fn memory_map_owned_buffer_uses_map_size ( ) {
624+ let mut memory = [ MemoryDescriptor :: default ( ) ; 4 ] ;
625+ memory[ ..BASE_MMAP_UNSORTED . len ( ) ] . copy_from_slice ( & BASE_MMAP_UNSORTED ) ;
626+
627+ let desc_size = size_of :: < MemoryDescriptor > ( ) ;
628+ let map_size = BASE_MMAP_UNSORTED . len ( ) * desc_size;
629+ let raw_len = size_of_val ( & memory) ;
630+ let raw = unsafe { core:: slice:: from_raw_parts_mut ( memory. as_mut_ptr ( ) . cast ( ) , raw_len) } ;
631+ let meta = MemoryMapMeta {
632+ map_size,
633+ desc_size,
634+ map_key : Default :: default ( ) ,
635+ desc_version : MemoryDescriptor :: VERSION ,
636+ } ;
637+
638+ let mmap = MemoryMapBackingMemory :: from_slice ( raw) ;
639+ let mut mmap = MemoryMapOwned :: from_initialized_mem ( mmap, meta) ;
640+
641+ assert_eq ! ( mmap. buffer( ) . len( ) , map_size) ;
642+ assert_eq ! ( unsafe { mmap. buffer_mut( ) } . len( ) , map_size) ;
643+ }
530644}
0 commit comments