Skip to content

Commit d72752a

Browse files
Alexandra IordacheSamuel Ortiz
authored andcommitted
fix potential hang condition in Elf::load
Fixed an unchecked arithmetic operation that could cause a hang. Attempting to load a malformed ELF kernel image which contains large enough numbers in the `n_namesz` and `n_descsz` fields of ELFNOTE headers can lead to arithmetic overflow, causing the `read_size` accumulator to wrap around and never exceed the maximum size condition of a while loop. Signed-off-by: Alexandra Iordache <aghecen@amazon.com> Signed-off-by: Andreea Florescu <fandree@amazon.com>
1 parent 0764ad3 commit d72752a

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

src/loader/x86_64/elf/mod.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ pub enum Error {
4444
InvalidProgramHeaderAddress,
4545
/// Invalid entry address.
4646
InvalidEntryAddress,
47+
/// Overflow occurred during an arithmetic operation.
48+
Overflow,
4749
/// Unable to read ELF header.
4850
ReadElfHeader,
4951
/// Unable to read kernel image.
@@ -76,6 +78,7 @@ impl fmt::Display for Error {
7678
Error::InvalidProgramHeaderOffset => "Invalid program header offset",
7779
Error::InvalidProgramHeaderAddress => "Invalid Program Header Address",
7880
Error::InvalidEntryAddress => "Invalid entry address",
81+
Error::Overflow => "Overflow occurred during an arithmetic operation",
7982
Error::ReadElfHeader => "Unable to read elf header",
8083
Error::ReadKernelImage => "Unable to read kernel image",
8184
Error::ReadProgramHeader => "Unable to read program header",
@@ -335,9 +338,13 @@ where
335338
}
336339

337340
// Skip the note header plus the size of its fields (with alignment).
338-
read_size += nhdr_sz
339-
+ align_up(u64::from(nhdr.n_namesz), n_align)?
340-
+ align_up(u64::from(nhdr.n_descsz), n_align)?;
341+
let namesz_aligned = align_up(u64::from(nhdr.n_namesz), n_align)?;
342+
let descsz_aligned = align_up(u64::from(nhdr.n_descsz), n_align)?;
343+
read_size = read_size
344+
.checked_add(nhdr_sz)
345+
.and_then(|read_size| read_size.checked_add(namesz_aligned))
346+
.and_then(|read_size| read_size.checked_add(descsz_aligned))
347+
.ok_or(Error::Overflow)?;
341348

342349
kernel_image
343350
.seek(SeekFrom::Start(phdr.p_offset + read_size as u64))

0 commit comments

Comments
 (0)