diff --git a/crates/examples/src/objdump.rs b/crates/examples/src/objdump.rs index 541bc876..257560aa 100644 --- a/crates/examples/src/objdump.rs +++ b/crates/examples/src/objdump.rs @@ -219,20 +219,28 @@ fn dump_parsed_object(w: &mut W, e: &mut E, file: &object::F } } - let imports = file.imports().unwrap(); - if !imports.is_empty() { - writeln!(w)?; - for import in imports { - writeln!(w, "{:?}", import)?; + match file.imports() { + Ok(imports) => { + if !imports.is_empty() { + writeln!(w)?; + for import in imports { + writeln!(w, "{:x?}", import)?; + } + } } + Err(err) => writeln!(e, "Failed to parse imports: {}", err)?, } - let exports = file.exports().unwrap(); - if !exports.is_empty() { - writeln!(w)?; - for export in exports { - writeln!(w, "{:x?}", export)?; + match file.exports() { + Ok(exports) => { + if !exports.is_empty() { + writeln!(w)?; + for export in exports { + writeln!(w, "{:x?}", export)?; + } + } } + Err(err) => writeln!(e, "Failed to parse exports: {}", err)?, } Ok(()) diff --git a/src/read/macho/load_command.rs b/src/read/macho/load_command.rs index 10daf4ed..e9af89d8 100644 --- a/src/read/macho/load_command.rs +++ b/src/read/macho/load_command.rs @@ -1,10 +1,11 @@ use core::marker::PhantomData; +use core::mem; use crate::endian::Endian; use crate::macho; use crate::pod::Pod; use crate::read::macho::{MachHeader, SymbolTable}; -use crate::read::{Bytes, ReadError, ReadRef, Result, StringTable}; +use crate::read::{Bytes, Error, ReadError, ReadRef, Result, StringTable}; /// An iterator over the load commands of a `MachHeader`. #[derive(Debug, Default, Clone, Copy)] @@ -34,6 +35,9 @@ impl<'data, E: Endian> LoadCommandIterator<'data, E> { .read_error("Invalid Mach-O load command header")?; let cmd = header.cmd.get(self.endian); let cmdsize = header.cmdsize.get(self.endian) as usize; + if cmdsize < mem::size_of::>() { + return Err(Error("Invalid Mach-O load command size")); + } let data = self .data .read_bytes(cmdsize) @@ -351,3 +355,19 @@ impl macho::SymtabCommand { Ok(SymbolTable::new(symbols, strings)) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::LittleEndian; + + #[test] + fn cmd_size_invalid() { + let mut commands = LoadCommandIterator::new(LittleEndian, &[0; 8], 10); + assert!(commands.next().is_err()); + let mut commands = LoadCommandIterator::new(LittleEndian, &[0, 0, 0, 0, 7, 0, 0, 0, 0], 10); + assert!(commands.next().is_err()); + let mut commands = LoadCommandIterator::new(LittleEndian, &[0, 0, 0, 0, 8, 0, 0, 0, 0], 10); + assert!(commands.next().is_ok()); + } +} diff --git a/src/read/macho/section.rs b/src/read/macho/section.rs index 9e71aa8f..d69174e5 100644 --- a/src/read/macho/section.rs +++ b/src/read/macho/section.rs @@ -120,7 +120,12 @@ where #[inline] fn align(&self) -> u64 { - 1 << self.internal.section.align(self.file.endian) + let align = self.internal.section.align(self.file.endian); + if align < 64 { + 1 << align + } else { + 0 + } } #[inline]