Check sh_type for symbol table and finish ProcessDIEs if any DIE processing goes wrong

- If symbol table section is malformed, skip them.
- SkipDIE and ProcessDIE return nullptr when processing goes wrong due to malformed debug info, stop processing in this case.

Bug: 1349354
Change-Id: Ia1d3e3591bbd2dad8b9eb351c1882cfc03bfad4b
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/3821448
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
Zequan Wu 2022-08-10 10:55:51 -07:00 committed by Joshua Peraza
parent 7e4ea04094
commit f1f7b5272f
2 changed files with 39 additions and 14 deletions

View file

@ -953,8 +953,22 @@ void CompilationUnit::ProcessDIEs() {
const enum DwarfTag tag = abbrev.tag; const enum DwarfTag tag = abbrev.tag;
if (!handler_->StartDIE(absolute_offset, tag)) { if (!handler_->StartDIE(absolute_offset, tag)) {
dieptr = SkipDIE(dieptr, abbrev); dieptr = SkipDIE(dieptr, abbrev);
if (!dieptr) {
fprintf(stderr,
"An error happens when skipping a DIE's attributes at offset "
"%lx. Stopped processing following DIEs in this CU.\n",
absolute_offset);
exit(1);
}
} else { } else {
dieptr = ProcessDIE(absolute_offset, dieptr, abbrev); dieptr = ProcessDIE(absolute_offset, dieptr, abbrev);
if (!dieptr) {
fprintf(stderr,
"An error happens when processing a DIE at offset %lx. Stopped "
"processing following DIEs in this CU.\n",
absolute_offset);
exit(1);
}
} }
if (abbrev.has_children) { if (abbrev.has_children) {

View file

@ -196,6 +196,17 @@ class ElfSectionReader {
// to process its contents. // to process its contents.
if (header_.sh_type == SHT_NOBITS || header_.sh_size == 0) if (header_.sh_type == SHT_NOBITS || header_.sh_size == 0)
return; return;
// extra sh_type check for string table.
if ((std::strcmp(name, ".strtab") == 0 ||
std::strcmp(name, ".shstrtab") == 0) &&
header_.sh_type != SHT_STRTAB) {
fprintf(stderr,
"Invalid sh_type for string table section: expected "
"SHT_STRTAB or SHT_DYNSYM, but got %d\n",
header_.sh_type);
return;
}
contents_aligned_ = mmap(NULL, size_aligned_, PROT_READ, MAP_SHARED, contents_aligned_ = mmap(NULL, size_aligned_, PROT_READ, MAP_SHARED,
fd, offset_aligned); fd, offset_aligned);
// Set where the offset really should begin. // Set where the offset really should begin.
@ -877,7 +888,7 @@ class ElfReaderImpl {
if (reader == NULL) if (reader == NULL)
reader = new ElfSectionReader<ElfArch>(name, path_, fd_, reader = new ElfSectionReader<ElfArch>(name, path_, fd_,
section_headers_[num]); section_headers_[num]);
return reader; return reader->contents() ? reader : nullptr;
} }
// Parse out the overall header information from the file and assert // Parse out the overall header information from the file and assert