Skip to content

Commit

Permalink
elf: Handle SHN_XINDEX for strtab section index (#304)
Browse files Browse the repository at this point in the history
This happens when the number of sections in an ELF object reaches 2^16,
at which point the u16 shstrndx takes the special value SHN_XINDEX.

Fix based on algorithm from:
github.com/gimli-rs/object/blob/c476071/src/read/elf/file.rs#L582-L600
  • Loading branch information
tux3 committed Jul 11, 2022
1 parent 3820091 commit 35663eb
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 3 deletions.
9 changes: 8 additions & 1 deletion src/elf/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,14 @@ if_sylvan! {

let section_headers = SectionHeader::parse(bytes, header.e_shoff as usize, header.e_shnum as usize, ctx)?;

let get_strtab = |section_headers: &[SectionHeader], section_idx: usize| {
let get_strtab = |section_headers: &[SectionHeader], mut section_idx: usize| {
if section_idx == section_header::SHN_XINDEX as usize {
if section_headers.is_empty() {
return Ok(Strtab::default())
}
section_idx = section_headers[0].sh_link as usize;
}

if section_idx >= section_headers.len() {
// FIXME: warn! here
Ok(Strtab::default())
Expand Down
9 changes: 7 additions & 2 deletions tests/elf.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use goblin::elf::section_header::SHT_GNU_HASH;
use goblin::elf::section_header::{SHN_XINDEX, SHT_GNU_HASH};
use goblin::elf::sym::{Sym, Symtab};
use goblin::elf::symver::{VerdefSection, VerneedSection, VersymSection};
use goblin::elf::Elf;
Expand Down Expand Up @@ -51,7 +51,12 @@ fn parse_text_section_size_lazy(base: &[u8]) -> Result<u64, &'static str> {
SectionHeader::parse(base, header.e_shoff as usize, header.e_shnum as usize, ctx)
.map_err(|_| "parse section headers error")?;

let strtab_idx = header.e_shstrndx as usize;
let strtab_idx = if header.e_shstrndx as u32 == SHN_XINDEX {
obj.section_headers[0].sh_link as usize
} else {
header.e_shstrndx as usize
};

let strtab_shdr = &obj.section_headers[strtab_idx];
let strtab = Strtab::parse(
base,
Expand Down

0 comments on commit 35663eb

Please sign in to comment.