aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDylan Noblesmith <nobled@dreamwidth.org>2012-02-04 02:41:39 +0000
committerDylan Noblesmith <nobled@dreamwidth.org>2012-02-04 02:41:39 +0000
commit069df954a1270cacbd477357dfbf116d47fdf254 (patch)
treeb7c7e2649fdf495193b7cbf7cf163519d119438e
parent3e82b4ad2a006c29da96a28c1b91c9b816503290 (diff)
downloadexternal_llvm-069df954a1270cacbd477357dfbf116d47fdf254.zip
external_llvm-069df954a1270cacbd477357dfbf116d47fdf254.tar.gz
external_llvm-069df954a1270cacbd477357dfbf116d47fdf254.tar.bz2
Object: avoid undefined behavior when bounds-checking
Don't form an out of bounds pointer just to test if it would be out of bounds. Also perform the same bounds checking for all the previous mapped structures. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149750 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Object/ELFObjectFile.cpp30
1 files changed, 22 insertions, 8 deletions
diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp
index 873d7b9..1b29cf6 100644
--- a/lib/Object/ELFObjectFile.cpp
+++ b/lib/Object/ELFObjectFile.cpp
@@ -1173,25 +1173,36 @@ ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object
, SectionHeaderTable(0)
, dot_shstrtab_sec(0)
, dot_strtab_sec(0) {
+
+ const uint64_t FileSize = Data->getBufferSize();
+
+ if (sizeof(Elf_Ehdr) > FileSize)
+ // FIXME: Proper error handling.
+ report_fatal_error("File too short!");
+
Header = reinterpret_cast<const Elf_Ehdr *>(base());
if (Header->e_shoff == 0)
return;
+ const uint64_t SectionTableOffset = Header->e_shoff;
+
+ if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
+ // FIXME: Proper error handling.
+ report_fatal_error("Section header table goes past end of file!");
+
+ // The getNumSections() call below depends on SectionHeaderTable being set.
SectionHeaderTable =
- reinterpret_cast<const Elf_Shdr *>(base() + Header->e_shoff);
- uint64_t SectionTableSize = getNumSections() * Header->e_shentsize;
+ reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
+ const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize;
- if ((const uint8_t *)SectionHeaderTable + SectionTableSize
- > base() + Data->getBufferSize()) {
+ if (SectionTableOffset + SectionTableSize > FileSize)
// FIXME: Proper error handling.
report_fatal_error("Section table goes past end of file!");
- }
-
// To find the symbol tables we walk the section table to find SHT_SYMTAB.
const Elf_Shdr* SymbolTableSectionHeaderIndex = 0;
- const Elf_Shdr* sh = reinterpret_cast<const Elf_Shdr*>(SectionHeaderTable);
+ const Elf_Shdr* sh = SectionHeaderTable;
for (uint64_t i = 0, e = getNumSections(); i != e; ++i) {
if (sh->sh_type == ELF::SHT_SYMTAB_SHNDX) {
if (SymbolTableSectionHeaderIndex)
@@ -1357,8 +1368,11 @@ unsigned ELFObjectFile<target_endianness, is64Bits>::getArch() const {
template<support::endianness target_endianness, bool is64Bits>
uint64_t ELFObjectFile<target_endianness, is64Bits>::getNumSections() const {
- if (Header->e_shnum == ELF::SHN_UNDEF)
+ assert(Header && "Header not initialized!");
+ if (Header->e_shnum == ELF::SHN_UNDEF) {
+ assert(SectionHeaderTable && "SectionHeaderTable not initialized!");
return SectionHeaderTable->sh_size;
+ }
return Header->e_shnum;
}