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

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: Replace uint32_t with Elf32_Off and add CHECK in ReduceLength 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
« no previous file with comments | « 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..be420d4179f319be5893e21c03eedef4bcfc82cf 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,8 +99,8 @@ bool DisassemblerElf32::Disassemble(AssemblyProgram* target) {
return true;
}
-uint32 DisassemblerElf32::DiscoverLength() {
- uint32 result = 0;
+bool DisassemblerElf32::UpdateLength() {
+ Elf32_Off result = 0;
// Find the end of the last section
for (int section_id = 0; section_id < SectionHeaderCount(); section_id++) {
@@ -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;
+ Elf32_Off 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;
+ Elf32_Off 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;
+ Elf32_Off section_table_end = header_->e_shoff +
+ (header_->e_shnum * sizeof(Elf32_Shdr));
+ 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;
+ Elf32_Off segment_table_end = header_->e_phoff +
+ (header_->e_phnum * sizeof(Elf32_Phdr));
+ result = std::max(result, segment_table_end);
- return result;
+ ReduceLength(result);
+ return true;
}
CheckBool DisassemblerElf32::IsValidRVA(RVA rva) const {
« no previous file with comments | « courgette/disassembler_elf_32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698