Skip to content

Commit c51e6e1

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 9f17f6b commit c51e6e1

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

src/loader/x86_64/elf/mod.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,9 @@ impl KernelLoader for Elf {
249249
}
250250
}
251251

252+
// Size of string "PVHNote", including the terminating NULL.
253+
const PVH_NOTE_STR_SZ: usize = 4;
254+
252255
/// Examines a supplied elf program header of type `PT_NOTE` to determine if it contains an entry
253256
/// of type `XEN_ELFNOTE_PHYS32_ENTRY` (0x12). Notes of this type encode a physical 32-bit entry
254257
/// point address into the kernel, which is used when launching guests in 32-bit (protected) mode
@@ -281,11 +284,18 @@ where
281284
.read_from(0, kernel_image, nhdr_sz)
282285
.map_err(|_| Error::ReadNoteHeader)?;
283286

284-
// If the note header found is not the desired one, keep reading until the end of the
285-
// segment.
286-
if nhdr.n_type == XEN_ELFNOTE_PHYS32_ENTRY {
287-
break;
287+
// If the note header found is not the desired one, keep reading until
288+
// the end of the segment
289+
if nhdr.n_type == XEN_ELFNOTE_PHYS32_ENTRY && nhdr.n_namesz as usize == PVH_NOTE_STR_SZ {
290+
let mut buf = [0u8; PVH_NOTE_STR_SZ];
291+
kernel_image
292+
.read_exact(&mut buf)
293+
.map_err(|_| Error::ReadNoteHeader)?;
294+
if buf == [b'x', b'e', b'n', b'\0'] {
295+
break;
296+
}
288297
}
298+
289299
// Skip the note header plus the size of its fields (with alignment).
290300
read_size += nhdr_sz
291301
+ align_up(u64::from(nhdr.n_namesz), n_align)
@@ -306,7 +316,7 @@ where
306316
// just skip the name field contents.
307317
kernel_image
308318
.seek(SeekFrom::Current(
309-
align_up(u64::from(nhdr.n_namesz), n_align) as i64,
319+
align_up(u64::from(nhdr.n_namesz), n_align) as i64 - PVH_NOTE_STR_SZ as i64,
310320
))
311321
.map_err(|_| Error::SeekNoteHeader)?;
312322

0 commit comments

Comments
 (0)