Skip to content

Commit

Permalink
Uniquely identify the PVH note header
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
jiangliu authored and Samuel Ortiz committed Apr 2, 2020
1 parent 02f61da commit af88796
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions src/loader/x86_64/elf/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,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
Expand Down Expand Up @@ -281,11 +284,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)
Expand All @@ -306,7 +315,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)?;

Expand Down
Binary file modified src/loader/x86_64/elf/test_badnote.bin
100755 → 100644
Binary file not shown.
Binary file modified src/loader/x86_64/elf/test_elfnote.bin
100755 → 100644
Binary file not shown.

0 comments on commit af88796

Please sign in to comment.