Skip to content

Commit 6ea4c5a

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 6ea4c5a

File tree

3 files changed

+14
-5
lines changed

3 files 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

src/loader/x86_64/elf/test_badnote.bin

100755100644
-8 Bytes
Binary file not shown.

src/loader/x86_64/elf/test_elfnote.bin

100755100644
-8 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)