Skip to content

Commit d19aea9

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 <gerry@linux.alibaba.com>
1 parent 9f17f6b commit d19aea9

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

src/loader/x86_64/elf/mod.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,9 @@ impl KernelLoader for Elf {
249249
}
250250
}
251251

252+
// Size of string "Xen", 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,17 @@ 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+
// Check if the note header's name and type match the ones specified by the PVH ABI.
288+
if nhdr.n_type == XEN_ELFNOTE_PHYS32_ENTRY && nhdr.n_namesz as usize == PVH_NOTE_STR_SZ {
289+
let mut buf = [0u8; PVH_NOTE_STR_SZ];
290+
kernel_image
291+
.read_exact(&mut buf)
292+
.map_err(|_| Error::ReadNoteHeader)?;
293+
if buf == [b'X', b'e', b'n', b'\0'] {
294+
break;
295+
}
288296
}
297+
289298
// Skip the note header plus the size of its fields (with alignment).
290299
read_size += nhdr_sz
291300
+ align_up(u64::from(nhdr.n_namesz), n_align)
@@ -306,7 +315,7 @@ where
306315
// just skip the name field contents.
307316
kernel_image
308317
.seek(SeekFrom::Current(
309-
align_up(u64::from(nhdr.n_namesz), n_align) as i64,
318+
align_up(u64::from(nhdr.n_namesz), n_align) as i64 - PVH_NOTE_STR_SZ as i64,
310319
))
311320
.map_err(|_| Error::SeekNoteHeader)?;
312321

0 commit comments

Comments
 (0)