@@ -29,7 +29,7 @@ use std::io::{Read, Seek};
2929#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
3030use std:: mem;
3131
32- use vm_memory:: { Address , Bytes , GuestAddress , GuestMemory , GuestUsize } ;
32+ use vm_memory:: { Address , ByteValued , Bytes , GuestAddress , GuestMemory , GuestUsize } ;
3333
3434#[ allow( dead_code) ]
3535#[ allow( non_camel_case_types) ]
@@ -51,9 +51,6 @@ pub mod start_info;
5151#[ allow( non_upper_case_globals) ]
5252#[ cfg_attr( feature = "cargo-clippy" , allow( clippy:: all) ) ]
5353mod elf;
54- #[ cfg( any( feature = "elf" , feature = "bzimage" ) ) ]
55- #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
56- mod struct_util;
5754
5855#[ derive( Debug , PartialEq ) ]
5956/// Kernel loader errors.
@@ -193,6 +190,18 @@ pub trait KernelLoader {
193190/// Raw ELF (a.k.a. vmlinux) kernel image support.
194191pub struct Elf ;
195192
193+ #[ cfg( feature = "elf" ) ]
194+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
195+ unsafe impl ByteValued for elf:: Elf64_Ehdr { }
196+ #[ cfg( feature = "elf" ) ]
197+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
198+ unsafe impl ByteValued for elf:: Elf64_Nhdr { }
199+ #[ cfg( feature = "elf" ) ]
200+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
201+ unsafe impl ByteValued for elf:: Elf64_Phdr { }
202+
203+ unsafe impl ByteValued for bootparam:: setup_header { }
204+
196205#[ cfg( feature = "elf" ) ]
197206#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
198207impl KernelLoader for Elf {
@@ -218,14 +227,14 @@ impl KernelLoader for Elf {
218227 where
219228 F : Read + Seek ,
220229 {
221- let mut ehdr: elf:: Elf64_Ehdr = Default :: default ( ) ;
222230 kernel_image
223231 . seek ( SeekFrom :: Start ( 0 ) )
224232 . map_err ( |_| Error :: SeekElfStart ) ?;
225- unsafe {
226- // read_struct is safe when reading a POD struct. It can be used and dropped without issue.
227- struct_util:: read_struct ( kernel_image, & mut ehdr) . map_err ( |_| Error :: ReadElfHeader ) ?;
228- }
233+
234+ let mut ehdr = elf:: Elf64_Ehdr :: default ( ) ;
235+ ehdr. as_bytes ( )
236+ . read_from ( 0 , kernel_image, mem:: size_of :: < elf:: Elf64_Ehdr > ( ) )
237+ . map_err ( |_| Error :: ReadElfHeader ) ?;
229238
230239 // Sanity checks
231240 if ehdr. e_ident [ elf:: EI_MAG0 as usize ] != elf:: ELFMAG0 as u8
@@ -260,18 +269,23 @@ impl KernelLoader for Elf {
260269 kernel_image
261270 . seek ( SeekFrom :: Start ( ehdr. e_phoff ) )
262271 . map_err ( |_| Error :: SeekProgramHeader ) ?;
263- let phdrs: Vec < elf:: Elf64_Phdr > = unsafe {
264- // Reading the structs is safe for a slice of POD structs.
265- struct_util:: read_struct_slice ( kernel_image, ehdr. e_phnum as usize )
266- . map_err ( |_| Error :: ReadProgramHeader ) ?
267- } ;
272+
273+ let phdr_sz = mem:: size_of :: < elf:: Elf64_Phdr > ( ) ;
274+ let mut phdrs: Vec < elf:: Elf64_Phdr > = vec ! [ ] ;
275+ for _ in 0usize ..ehdr. e_phnum as usize {
276+ let mut phdr = elf:: Elf64_Phdr :: default ( ) ;
277+ phdr. as_bytes ( )
278+ . read_from ( 0 , kernel_image, phdr_sz)
279+ . map_err ( |_| Error :: ReadProgramHeader ) ?;
280+ phdrs. push ( phdr) ;
281+ }
268282
269283 // Read in each section pointed to by the program headers.
270- for phdr in & phdrs {
284+ for phdr in phdrs {
271285 if phdr. p_type != elf:: PT_LOAD || phdr. p_filesz == 0 {
272286 if phdr. p_type == elf:: PT_NOTE {
273287 // This segment describes a Note, check if PVH entry point is encoded.
274- loader_result. pvh_entry_addr = parse_elf_note ( phdr, kernel_image) ?;
288+ loader_result. pvh_entry_addr = parse_elf_note ( & phdr, kernel_image) ?;
275289 }
276290 continue ;
277291 }
@@ -327,20 +341,20 @@ where
327341 // correct type that encodes the PVH entry point if there is one.
328342 let mut nhdr: elf:: Elf64_Nhdr = Default :: default ( ) ;
329343 let mut read_size: usize = 0 ;
344+ let nhdr_sz = mem:: size_of :: < elf:: Elf64_Nhdr > ( ) ;
330345
331346 while read_size < phdr. p_filesz as usize {
332- unsafe {
333- // read_struct is safe when reading a POD struct.
334- // It can be used and dropped without issue.
335- struct_util:: read_struct ( kernel_image, & mut nhdr) . map_err ( |_| Error :: ReadNoteHeader ) ?;
336- }
347+ nhdr. as_bytes ( )
348+ . read_from ( 0 , kernel_image, nhdr_sz)
349+ . map_err ( |_| Error :: ReadNoteHeader ) ?;
350+
337351 // If the note header found is not the desired one, keep reading until
338352 // the end of the segment
339353 if nhdr. n_type == XEN_ELFNOTE_PHYS32_ENTRY {
340354 break ;
341355 }
342356 // Skip the note header plus the size of its fields (with alignment)
343- read_size += mem :: size_of :: < elf :: Elf64_Nhdr > ( )
357+ read_size += nhdr_sz
344358 + align_up ( u64:: from ( nhdr. n_namesz ) , n_align)
345359 + align_up ( u64:: from ( nhdr. n_descsz ) , n_align) ;
346360
@@ -413,15 +427,15 @@ impl KernelLoader for BzImage {
413427 let mut kernel_size = kernel_image
414428 . seek ( SeekFrom :: End ( 0 ) )
415429 . map_err ( |_| Error :: SeekBzImageEnd ) ? as usize ;
416- let mut boot_header: bootparam:: setup_header = Default :: default ( ) ;
417430 kernel_image
418431 . seek ( SeekFrom :: Start ( 0x1F1 ) )
419432 . map_err ( |_| Error :: SeekBzImageHeader ) ?;
420- unsafe {
421- // read_struct is safe when reading a POD struct. It can be used and dropped without issue.
422- struct_util:: read_struct ( kernel_image, & mut boot_header)
423- . map_err ( |_| Error :: ReadBzImageHeader ) ?;
424- }
433+
434+ let mut boot_header = bootparam:: setup_header:: default ( ) ;
435+ boot_header
436+ . as_bytes ( )
437+ . read_from ( 0 , kernel_image, mem:: size_of :: < bootparam:: setup_header > ( ) )
438+ . map_err ( |_| Error :: ReadBzImageHeader ) ?;
425439
426440 // if the HdrS magic number is not found at offset 0x202, the boot protocol version is "old",
427441 // the image type is assumed as zImage, not bzImage.
0 commit comments