@@ -29,7 +29,7 @@ use std::io::{Read, Seek};
29
29
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
30
30
use std:: mem;
31
31
32
- use vm_memory:: { Address , Bytes , GuestAddress , GuestMemory , GuestUsize } ;
32
+ use vm_memory:: { Address , ByteValued , Bytes , GuestAddress , GuestMemory , GuestUsize } ;
33
33
34
34
#[ allow( dead_code) ]
35
35
#[ allow( non_camel_case_types) ]
@@ -51,9 +51,6 @@ pub mod start_info;
51
51
#[ allow( non_upper_case_globals) ]
52
52
#[ cfg_attr( feature = "cargo-clippy" , allow( clippy:: all) ) ]
53
53
mod elf;
54
- #[ cfg( any( feature = "elf" , feature = "bzimage" ) ) ]
55
- #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
56
- mod struct_util;
57
54
58
55
#[ derive( Debug , PartialEq ) ]
59
56
/// Kernel loader errors.
@@ -193,6 +190,18 @@ pub trait KernelLoader {
193
190
/// Raw ELF (a.k.a. vmlinux) kernel image support.
194
191
pub struct Elf ;
195
192
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
+
196
205
#[ cfg( feature = "elf" ) ]
197
206
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
198
207
impl KernelLoader for Elf {
@@ -218,14 +227,14 @@ impl KernelLoader for Elf {
218
227
where
219
228
F : Read + Seek ,
220
229
{
221
- let mut ehdr: elf:: Elf64_Ehdr = Default :: default ( ) ;
222
230
kernel_image
223
231
. seek ( SeekFrom :: Start ( 0 ) )
224
232
. 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 ) ?;
229
238
230
239
// Sanity checks
231
240
if ehdr. e_ident [ elf:: EI_MAG0 as usize ] != elf:: ELFMAG0 as u8
@@ -260,18 +269,23 @@ impl KernelLoader for Elf {
260
269
kernel_image
261
270
. seek ( SeekFrom :: Start ( ehdr. e_phoff ) )
262
271
. 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
+ }
268
282
269
283
// Read in each section pointed to by the program headers.
270
- for phdr in & phdrs {
284
+ for phdr in phdrs {
271
285
if phdr. p_type != elf:: PT_LOAD || phdr. p_filesz == 0 {
272
286
if phdr. p_type == elf:: PT_NOTE {
273
287
// 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) ?;
275
289
}
276
290
continue ;
277
291
}
@@ -327,20 +341,20 @@ where
327
341
// correct type that encodes the PVH entry point if there is one.
328
342
let mut nhdr: elf:: Elf64_Nhdr = Default :: default ( ) ;
329
343
let mut read_size: usize = 0 ;
344
+ let nhdr_sz = mem:: size_of :: < elf:: Elf64_Nhdr > ( ) ;
330
345
331
346
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
+
337
351
// If the note header found is not the desired one, keep reading until
338
352
// the end of the segment
339
353
if nhdr. n_type == XEN_ELFNOTE_PHYS32_ENTRY {
340
354
break ;
341
355
}
342
356
// 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
344
358
+ align_up ( u64:: from ( nhdr. n_namesz ) , n_align)
345
359
+ align_up ( u64:: from ( nhdr. n_descsz ) , n_align) ;
346
360
@@ -413,15 +427,15 @@ impl KernelLoader for BzImage {
413
427
let mut kernel_size = kernel_image
414
428
. seek ( SeekFrom :: End ( 0 ) )
415
429
. map_err ( |_| Error :: SeekBzImageEnd ) ? as usize ;
416
- let mut boot_header: bootparam:: setup_header = Default :: default ( ) ;
417
430
kernel_image
418
431
. seek ( SeekFrom :: Start ( 0x1F1 ) )
419
432
. 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 ) ?;
425
439
426
440
// if the HdrS magic number is not found at offset 0x202, the boot protocol version is "old",
427
441
// the image type is assumed as zImage, not bzImage.
0 commit comments