Skip to content

Commit 8a901e2

Browse files
committed
TE: fix subtract with overflow in TE header parser
1 parent ac1fabd commit 8a901e2

1 file changed

Lines changed: 38 additions & 2 deletions

File tree

src/pe/header.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,8 +1209,16 @@ pub const TE_MAGIC: u16 = 0x5a56;
12091209
impl TeHeader {
12101210
/// Parse the TE header from the given bytes.
12111211
pub fn parse(bytes: &[u8], offset: &mut usize) -> error::Result<Self> {
1212+
const HEADER_SIZE: usize = core::mem::size_of::<TeHeader>();
12121213
let mut header: TeHeader = bytes.gread_with(offset, scroll::LE)?;
1213-
let adj_offset = header.stripped_size as u32 - core::mem::size_of::<TeHeader>() as u32;
1214+
let stripped_size = header.stripped_size as u32;
1215+
let adj_offset = stripped_size
1216+
.checked_sub(HEADER_SIZE as u32)
1217+
.ok_or_else(|| {
1218+
error::Error::Malformed(format!(
1219+
"Stripped size ({stripped_size:#x}) is smaller than TE header size ({HEADER_SIZE:#x})",
1220+
))
1221+
})?;
12141222
header.fixup_header(adj_offset);
12151223
Ok(header)
12161224
}
@@ -1352,7 +1360,10 @@ pub fn machine_to_str(machine: u16) -> &'static str {
13521360

13531361
#[cfg(test)]
13541362
mod tests {
1355-
use crate::{error, pe::header::DosStub};
1363+
use crate::{
1364+
error,
1365+
pe::header::{DosStub, TeHeader},
1366+
};
13561367

13571368
use super::{
13581369
machine_to_str, Header, RichHeader, RichMetadata, COFF_MACHINE_X86, DOS_MAGIC, PE_MAGIC,
@@ -1534,6 +1545,16 @@ mod tests {
15341545
0x00,
15351546
];
15361547

1548+
/// Malformed very small TE with valid TE magic.
1549+
///
1550+
/// https://github.com/m4b/goblin/issues/450
1551+
const MALFORMED_SMALL_TE: [u8; 58] = [
1552+
0x56, 0x5A, 0x52, 0x5A, 0x50, 0x00, 0x17, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00,
1553+
0x10, 0x86, 0x02, 0x0C, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x1B, 0x01, 0x01, 0x00, 0x00,
1554+
0xFF, 0xB5, 0x00, 0x00, 0x00, 0x04, 0x34, 0x00, 0x00, 0xFF, 0xB5, 0x00, 0x00, 0x00, 0x04,
1555+
0x34, 0x15, 0x40, 0x13, 0x41, 0x0E, 0x10, 0x15, 0x40, 0x13, 0x41, 0x0E, 0x10,
1556+
];
1557+
15371558
#[test]
15381559
fn crss_header() {
15391560
let header = Header::parse(&&CRSS_HEADER[..]).unwrap();
@@ -1656,4 +1677,19 @@ mod tests {
16561677
let header_result = RichHeader::parse(&CORRUPTED_RICH_HEADER);
16571678
assert_eq!(header_result.is_err(), true);
16581679
}
1680+
1681+
#[test]
1682+
fn parse_malformed_small_te() {
1683+
let mut offset = 0;
1684+
let header = TeHeader::parse(&MALFORMED_SMALL_TE, &mut offset);
1685+
assert_eq!(header.is_err(), true);
1686+
if let Err(error::Error::Malformed(msg)) = header {
1687+
assert_eq!(
1688+
msg,
1689+
"Stripped size (0x17) is smaller than TE header size (0x28)"
1690+
);
1691+
} else {
1692+
panic!("Expected a Malformed error but got {:?}", header);
1693+
}
1694+
}
16591695
}

0 commit comments

Comments
 (0)