diff --git a/Cargo.toml b/Cargo.toml index b5a2fa0f..e3e37713 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,7 @@ bzimage = [] pe = [] [dependencies] -vm-memory = {version = ">=0.2.0", features = ["backend-mmap"]} +vm-memory = ">=0.2.0" + +[dev-dependencies] +vm-memory = {features = ["backend-mmap"]} diff --git a/coverage_config_x86_64.json b/coverage_config_x86_64.json index 27f86931..898d1bf0 100644 --- a/coverage_config_x86_64.json +++ b/coverage_config_x86_64.json @@ -1,5 +1,5 @@ { - "coverage_score": 74.7, + "coverage_score": 74.8, "exclude_path": "", "crate_features": "" } diff --git a/src/loader/x86_64/elf/mod.rs b/src/loader/x86_64/elf/mod.rs index 347e1c72..4b6de40b 100644 --- a/src/loader/x86_64/elf/mod.rs +++ b/src/loader/x86_64/elf/mod.rs @@ -236,10 +236,11 @@ impl KernelLoader for Elf { .read_exact_from(mem_offset, kernel_image, phdr.p_filesz as usize) .map_err(|_| Error::ReadKernelImage)?; - loader_result.kernel_end = mem_offset + let kernel_end = mem_offset .raw_value() .checked_add(phdr.p_memsz as GuestUsize) .ok_or(KernelLoaderError::MemoryOverflow)?; + loader_result.kernel_end = std::cmp::max(loader_result.kernel_end, kernel_end); } // elf image has no setup_header which is defined for bzImage @@ -249,6 +250,9 @@ impl KernelLoader for Elf { } } +// Size of string "Xen", including the terminating NULL. +const PVH_NOTE_STR_SZ: usize = 4; + /// Examines a supplied elf program header of type `PT_NOTE` to determine if it contains an entry /// of type `XEN_ELFNOTE_PHYS32_ENTRY` (0x12). Notes of this type encode a physical 32-bit entry /// point address into the kernel, which is used when launching guests in 32-bit (protected) mode @@ -281,11 +285,17 @@ where .read_from(0, kernel_image, nhdr_sz) .map_err(|_| Error::ReadNoteHeader)?; - // If the note header found is not the desired one, keep reading until the end of the - // segment. - if nhdr.n_type == XEN_ELFNOTE_PHYS32_ENTRY { - break; + // Check if the note header's name and type match the ones specified by the PVH ABI. + if nhdr.n_type == XEN_ELFNOTE_PHYS32_ENTRY && nhdr.n_namesz as usize == PVH_NOTE_STR_SZ { + let mut buf = [0u8; PVH_NOTE_STR_SZ]; + kernel_image + .read_exact(&mut buf) + .map_err(|_| Error::ReadNoteHeader)?; + if buf == [b'X', b'e', b'n', b'\0'] { + break; + } } + // Skip the note header plus the size of its fields (with alignment). read_size += nhdr_sz + align_up(u64::from(nhdr.n_namesz), n_align) @@ -306,7 +316,7 @@ where // just skip the name field contents. kernel_image .seek(SeekFrom::Current( - align_up(u64::from(nhdr.n_namesz), n_align) as i64, + align_up(u64::from(nhdr.n_namesz), n_align) as i64 - PVH_NOTE_STR_SZ as i64, )) .map_err(|_| Error::SeekNoteHeader)?; diff --git a/src/loader/x86_64/elf/test_badnote.bin b/src/loader/x86_64/elf/test_badnote.bin old mode 100755 new mode 100644 index cbe4cb59..99013dd5 Binary files a/src/loader/x86_64/elf/test_badnote.bin and b/src/loader/x86_64/elf/test_badnote.bin differ diff --git a/src/loader/x86_64/elf/test_elfnote.bin b/src/loader/x86_64/elf/test_elfnote.bin old mode 100755 new mode 100644 index 36efd2d3..e2fc7faa Binary files a/src/loader/x86_64/elf/test_elfnote.bin and b/src/loader/x86_64/elf/test_elfnote.bin differ