@@ -384,6 +384,64 @@ pub fn mshv_vsm_validate_guest_module(pa: u64, nranges: u64, _flags: u64) -> Res
384384 // the kernel module's original ELF binary which is signed by the kernel build pipeline
385385 let mut module_as_elf = MemoryContainer :: new ( ) ;
386386
387+ prepare_data_for_module_validation (
388+ pa,
389+ nranges,
390+ & mut module_memory_metadata,
391+ & mut module_in_memory,
392+ & mut module_as_elf,
393+ ) ?;
394+
395+ let elf_size = module_as_elf. len ( ) ;
396+ assert ! (
397+ elf_size <= MODULE_VALIDATION_MAX_SIZE ,
398+ "Module ELF size exceeds the maximum allowed size"
399+ ) ;
400+
401+ let mut original_elf_data = vec ! [ 0u8 ; elf_size] ;
402+ module_as_elf
403+ . read_bytes ( module_as_elf. start ( ) . unwrap ( ) , & mut original_elf_data)
404+ . map_err ( |_| Errno :: EINVAL ) ?;
405+ module_as_elf. clear ( ) ;
406+
407+ #[ cfg( debug_assertions) ]
408+ parse_modinfo ( & original_elf_data) . map_err ( |_| Errno :: EINVAL ) ?;
409+
410+ if !validate_kernel_module_against_elf ( & module_in_memory, & original_elf_data)
411+ . map_err ( |_| Errno :: EINVAL ) ?
412+ {
413+ serial_println ! ( "VSM: Found unexpected relocations in the loaded module" ) ;
414+ return Err ( Errno :: EINVAL ) ;
415+ }
416+
417+ // protect the memory ranges of a module based on their section types
418+ for mod_mem_range in & module_memory_metadata {
419+ protect_physical_memory_range (
420+ mod_mem_range. phys_frame_range ,
421+ mod_mem_type_to_mem_attr ( mod_mem_range. mod_mem_type ) ,
422+ ) ?;
423+ }
424+
425+ // register the module memory in the global map and obtain a unique token for it
426+ let token = crate :: platform_low ( )
427+ . vtl0_kernel_info
428+ . module_memory_metadata
429+ . register_module_memory_metadata ( module_memory_metadata) ;
430+ Ok ( token)
431+ }
432+
433+ // TODO: several VSM functions have similar VTL0 page walking and copying code. Combine them to avoid redundancy.
434+ /// This function copies data for module validation from VTL0 to VTL1
435+ ///
436+ /// # Safety
437+ /// The caller must ensure that the provided `pa` and `nranges` are valid.
438+ fn prepare_data_for_module_validation (
439+ pa : u64 ,
440+ nranges : u64 ,
441+ module_memory_metadata : & mut ModuleMemoryMetadata ,
442+ module_in_memory : & mut ModuleMemory ,
443+ module_as_elf : & mut MemoryContainer ,
444+ ) -> Result < ( ) , Errno > {
387445 if let Some ( heki_pages) = copy_heki_pages_from_vtl0 ( pa, nranges) {
388446 for heki_page in heki_pages {
389447 for i in 0 ..usize:: try_from ( heki_page. nranges ) . unwrap_or ( 0 ) {
@@ -435,46 +493,10 @@ pub fn mshv_vsm_validate_guest_module(pa: u64, nranges: u64, _flags: u64) -> Res
435493 }
436494 }
437495 }
496+ Ok ( ( ) )
438497 } else {
439- return Err ( Errno :: EINVAL ) ;
440- }
441-
442- let elf_size = module_as_elf. len ( ) ;
443- assert ! (
444- elf_size <= MODULE_VALIDATION_MAX_SIZE ,
445- "Module ELF size exceeds the maximum allowed size"
446- ) ;
447-
448- let mut original_elf_data = vec ! [ 0u8 ; elf_size] ;
449- module_as_elf
450- . read_bytes ( module_as_elf. start ( ) . unwrap ( ) , & mut original_elf_data)
451- . map_err ( |_| Errno :: EINVAL ) ?;
452- module_as_elf. clear ( ) ;
453-
454- #[ cfg( debug_assertions) ]
455- parse_modinfo ( & original_elf_data) . map_err ( |_| Errno :: EINVAL ) ?;
456-
457- if !validate_kernel_module_against_elf ( & module_in_memory, & original_elf_data)
458- . map_err ( |_| Errno :: EINVAL ) ?
459- {
460- serial_println ! ( "VSM: Found unexpected relocations in the loaded module" ) ;
461- return Err ( Errno :: EINVAL ) ;
462- }
463-
464- // protect the memory ranges of a module based on their section types
465- for mod_mem_range in & module_memory_metadata {
466- protect_physical_memory_range (
467- mod_mem_range. phys_frame_range ,
468- mod_mem_type_to_mem_attr ( mod_mem_range. mod_mem_type ) ,
469- ) ?;
498+ Err ( Errno :: EINVAL )
470499 }
471-
472- // register the module memory in the global map and obtain a unique token for it
473- let token = crate :: platform_low ( )
474- . vtl0_kernel_info
475- . module_memory_metadata
476- . register_module_memory_metadata ( module_memory_metadata) ;
477- Ok ( token)
478500}
479501
480502/// VSM function for supporting the initialization of a guest kernel module including
0 commit comments