Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Unified Diff: courgette/disassembler_elf_32.cc

Issue 1031513002: Robust ELF header parsing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« courgette/disassembler.cc ('K') | « courgette/disassembler_elf_32.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: courgette/disassembler_elf_32.cc
diff --git a/courgette/disassembler_elf_32.cc b/courgette/disassembler_elf_32.cc
index 02a31eb6dd734f2353bb228c7847d2d8592e95e0..ec7cef541f9fff172ee467b09347476a85d7a632 100644
--- a/courgette/disassembler_elf_32.cc
+++ b/courgette/disassembler_elf_32.cc
@@ -54,27 +54,26 @@ bool DisassemblerElf32::ParseHeader() {
if (header_->e_shentsize != sizeof(Elf32_Shdr))
return Bad("Unexpected section header size");
- if (header_->e_shoff >= length())
- return Bad("Out of bounds section header table offset");
+ if (!IsArrayInBounds(header_->e_shoff, header_->e_shnum, sizeof(Elf32_Shdr)))
+ return Bad("Out of bounds section header table");
section_header_table_ = (Elf32_Shdr *)OffsetToPointer(header_->e_shoff);
section_header_table_size_ = header_->e_shnum;
- if ((header_->e_shoff + header_->e_shnum ) >= length())
- return Bad("Out of bounds section header table");
-
- if (header_->e_phoff >= length())
- return Bad("Out of bounds program header table offset");
+ if (!IsArrayInBounds(header_->e_phoff, header_->e_phnum, sizeof(Elf32_Phdr)))
+ return Bad("Out of bounds program header table");
program_header_table_ = (Elf32_Phdr *)OffsetToPointer(header_->e_phoff);
program_header_table_size_ = header_->e_phnum;
- if ((header_->e_phoff + header_->e_phnum) >= length())
- return Bad("Out of bounds program header table");
+ if (header_->e_shstrndx >= header_->e_shnum)
+ return Bad("Out of bounds string section index");
default_string_section_ = (const char *)SectionBody((int)header_->e_shstrndx);
- ReduceLength(DiscoverLength());
+ if (!UpdateLength()) {
+ return Bad("Out of bounds section or segment");
+ }
return Good();
}
@@ -100,7 +99,7 @@ bool DisassemblerElf32::Disassemble(AssemblyProgram* target) {
return true;
}
-uint32 DisassemblerElf32::DiscoverLength() {
+bool DisassemblerElf32::UpdateLength() {
uint32 result = 0;
rickyz (no longer on Chrome) 2015/03/23 23:14:50 Mind changing this to an Elf32_Off as well?
halyavin2 2015/03/24 14:35:18 Done. I just realized there is one more bug to f
// Find the end of the last section
@@ -110,33 +109,34 @@ uint32 DisassemblerElf32::DiscoverLength() {
if (section_header->sh_type == SHT_NOBITS)
continue;
- uint32 section_end = section_header->sh_offset + section_header->sh_size;
+ if (!IsArrayInBounds(section_header->sh_offset, section_header->sh_size, 1))
+ return false;
- if (section_end > result)
- result = section_end;
+ uint32 section_end = section_header->sh_offset + section_header->sh_size;
+ result = std::max(result, section_end);
}
// Find the end of the last segment
for (int i = 0; i < ProgramSegmentHeaderCount(); i++) {
const Elf32_Phdr *segment_header = ProgramSegmentHeader(i);
- uint32 segment_end = segment_header->p_offset + segment_header->p_filesz;
+ if (!IsArrayInBounds(segment_header->p_offset, segment_header->p_filesz, 1))
+ return false;
- if (segment_end > result)
- result = segment_end;
+ uint32 segment_end = segment_header->p_offset + segment_header->p_filesz;
+ result = std::max(result, segment_end);
}
uint32 section_table_end = header_->e_shoff +
(header_->e_shnum * sizeof(Elf32_Shdr));
- if (section_table_end > result)
- result = section_table_end;
+ result = std::max(result, section_table_end);
uint32 segment_table_end = header_->e_phoff +
(header_->e_phnum * sizeof(Elf32_Phdr));
- if (segment_table_end > result)
- result = segment_table_end;
+ result = std::max(result, segment_table_end);
- return result;
+ ReduceLength(result);
+ return true;
}
CheckBool DisassemblerElf32::IsValidRVA(RVA rva) const {
« courgette/disassembler.cc ('K') | « courgette/disassembler_elf_32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698