Skip to content

Commit dc38cc8

Browse files
committed
Uniquely identify the PVH note header
According to Linux kernel documentation: Each note has three parts: a name, a type and a desc. The name is intended to distinguish the note's originator, so it would be a company, project, subsystem, etc; it must be in a suitable form for use in a section name. The type is an integer which is used to tag the data, and is considered to be within the "name" namespace (so "FooCo"'s type 42 is distinct from "BarProj"'s type 42). The "desc" field is the actual data. There are no constraints on the desc field's contents, though typically they're fairly small. So check both name and type when searching for the PVH note. Signed-off-by: Liu Jiang <[email protected]>
1 parent 7e277bc commit dc38cc8

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

src/loader/mod.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,11 @@ impl KernelLoader for Elf {
306306
}
307307
}
308308

309+
#[cfg(feature = "elf")]
310+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
311+
// Size of string "PVHNote", including the terminating NULL.
312+
const PVH_NOTE_STR_SZ: usize = 8;
313+
309314
#[cfg(feature = "elf")]
310315
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
311316
fn parse_elf_note<F>(phdr: &elf::Elf64_Phdr, kernel_image: &mut F) -> Result<Option<GuestAddress>>
@@ -336,9 +341,16 @@ where
336341
}
337342
// If the note header found is not the desired one, keep reading until
338343
// the end of the segment
339-
if nhdr.n_type == XEN_ELFNOTE_PHYS32_ENTRY {
340-
break;
344+
if nhdr.n_type == XEN_ELFNOTE_PHYS32_ENTRY && nhdr.n_namesz as usize == PVH_NOTE_STR_SZ {
345+
let mut buf = [0u8; PVH_NOTE_STR_SZ];
346+
kernel_image
347+
.read_exact(&mut buf)
348+
.map_err(|_| Error::ReadNoteHeader)?;
349+
if buf == [b'P', b'V', b'H', b'N', b'o', b't', b'e', b'\0'] {
350+
break;
351+
}
341352
}
353+
342354
// Skip the note header plus the size of its fields (with alignment)
343355
read_size += mem::size_of::<elf::Elf64_Nhdr>()
344356
+ align_up(u64::from(nhdr.n_namesz), n_align)
@@ -357,7 +369,7 @@ where
357369
// current position and just skip the name field contents.
358370
kernel_image
359371
.seek(SeekFrom::Current(
360-
align_up(u64::from(nhdr.n_namesz), n_align) as i64,
372+
align_up(u64::from(nhdr.n_namesz), n_align) as i64 - PVH_NOTE_STR_SZ as i64,
361373
))
362374
.map_err(|_| Error::SeekNoteHeader)?;
363375

0 commit comments

Comments
 (0)