From: George Rimar Date: Fri, 7 Jun 2019 08:34:18 +0000 (+0000) Subject: [llvm-objcopy] - Emit error and don't crash if program header reaches past end of... X-Git-Tag: android-x86-9.0-r1~2296 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=10b2fe521d3ebbfb52da805d9d8be572e84360fb;p=android-x86%2Fexternal-llvm.git [llvm-objcopy] - Emit error and don't crash if program header reaches past end of file. This is https://bugs.llvm.org/show_bug.cgi?id=42122. If an object file has a size less than program header's file [offset + size] (i.e. if we have overflow), llvm-objcopy crashes instead of reporting a error. The patch fixes this issue. Differential revision: https://reviews.llvm.org/D62898 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362778 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/llvm-objcopy/ELF/invalid-p_filesz-p_offset.test b/test/tools/llvm-objcopy/ELF/invalid-p_filesz-p_offset.test new file mode 100644 index 00000000000..fdb54da5d73 --- /dev/null +++ b/test/tools/llvm-objcopy/ELF/invalid-p_filesz-p_offset.test @@ -0,0 +1,45 @@ +## In this case, we have a program header with a file size that +## overflows the binary size. Check llvm-objcopy doesn't crash +## and report this error properly. + +# RUN: yaml2obj --docnum=1 %s -o %t1.o +# RUN: not llvm-objcopy %t1.o 2>&1 | FileCheck %s --check-prefix=ERR1 +# ERR1: error: program header with offset 0x1b8 and file size 0x100000 goes past the end of the file + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .foo + Type: SHT_PROGBITS +ProgramHeaders: + - Type: PT_LOAD + FileSize: 0x100000 + Sections: + - Section: .foo + +## A similar case, but now the p_offset property of the program header is too large. + +# RUN: yaml2obj --docnum=2 %s -o %t2.o +# RUN: not llvm-objcopy %t2.o 2>&1 | FileCheck %s --check-prefix=ERR2 +# ERR2: error: program header with offset 0x100000 and file size 0x1 goes past the end of the file + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .foo + Type: SHT_PROGBITS + Size: 1 +ProgramHeaders: + - Type: PT_LOAD + Offset: 0x100000 + FileSize: 1 + Sections: + - Section: .foo diff --git a/tools/llvm-objcopy/ELF/Object.cpp b/tools/llvm-objcopy/ELF/Object.cpp index e70a3b1fde1..b654305474f 100644 --- a/tools/llvm-objcopy/ELF/Object.cpp +++ b/tools/llvm-objcopy/ELF/Object.cpp @@ -1104,6 +1104,11 @@ template void ELFBuilder::setParentSegment(Segment &Child) { template void ELFBuilder::readProgramHeaders() { uint32_t Index = 0; for (const auto &Phdr : unwrapOrError(ElfFile.program_headers())) { + if (Phdr.p_offset + Phdr.p_filesz > ElfFile.getBufSize()) + error("program header with offset 0x" + Twine::utohexstr(Phdr.p_offset) + + " and file size 0x" + Twine::utohexstr(Phdr.p_filesz) + + " goes past the end of the file"); + ArrayRef Data{ElfFile.base() + Phdr.p_offset, (size_t)Phdr.p_filesz}; Segment &Seg = Obj.addSegment(Data);