[PATCH] D83774: [llvm-readobj] - Verify the location of program headers better.
George Rimar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 14 07:28:31 PDT 2020
grimar created this revision.
grimar added reviewers: jhenderson, MaskRay.
Herald added subscribers: rupprecht, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.
This improves condition in the ELFFile::program_headers().
Previously if was possible to read the headers from the wrong place when
the value of e_phoff was so large that computation overflowed.
https://reviews.llvm.org/D83774
Files:
llvm/include/llvm/Object/ELF.h
llvm/test/tools/llvm-readobj/ELF/gnu-phdrs.test
Index: llvm/test/tools/llvm-readobj/ELF/gnu-phdrs.test
===================================================================
--- llvm/test/tools/llvm-readobj/ELF/gnu-phdrs.test
+++ llvm/test/tools/llvm-readobj/ELF/gnu-phdrs.test
@@ -356,7 +356,8 @@
Offset: 0xAABBCCDDEEFF1122
## Check we report a warning when we are unable to read program headers.
-# RUN: yaml2obj --docnum=3 %s -o %t.phdr.err
+## Case A: the e_phentsize field is invalid.
+# RUN: yaml2obj --docnum=3 -DPHENTSIZE=1 %s -o %t.phdr.err
# RUN: llvm-readelf --program-headers %t.phdr.err 2>&1 | \
# RUN: FileCheck %s -DFILE=%t.phdr.err --check-prefix=WARN-PHENTSIZE
@@ -373,7 +374,8 @@
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_X86_64
- EPhEntSize: 1
+ EPhEntSize: [[PHENTSIZE=56]]
+ EPhOff: [[PHOFF=64]]
Sections:
- Name: .foo
Type: SHT_PROGBITS
@@ -381,3 +383,28 @@
- Type: PT_PHDR
Sections:
- Section: .foo
+
+## Case B: the value of the e_phoff field is invalid.
+
+## Check that we do not report a warning when program headers ends right before the end of the file.
+## 0x160 + size of headers (56) == file size.
+# RUN: yaml2obj --docnum=3 -DPHOFF=0x160 %s -o %t.phdr.no.err2
+# RUN: llvm-readelf %t.phdr.no.err2 --program-headers 2>&1 | FileCheck %s --implicit-check-not=warning:
+
+## Check we report a warning when e_phoff goes 1 byte past the end of the file.
+# RUN: yaml2obj --docnum=3 -DPHOFF=0x161 %s -o %t.phdr.err2
+# RUN: llvm-readelf --program-headers %t.phdr.err2 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t.phdr.err2 --check-prefix=WARN-PHOFF -DOFF=0x161
+
+# WARN-PHOFF: Program Headers:
+# WARN-PHOFF-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
+# WARN-PHOFF-NEXT: warning: '[[FILE]]': unable to dump program headers: program headers are longer than binary of size 408: e_phoff = [[OFF]], e_phnum = 1, e_phentsize = 56
+# WARN-PHOFF: Section to Segment mapping:
+# WARN-PHOFF-NEXT: Segment Sections...
+# WARN-PHOFF-NEXT: warning: '[[FILE]]': can't read program headers to build section to segment mapping: program headers are longer than binary of size 408: e_phoff = [[OFF]], e_phnum = 1, e_phentsize = 56
+
+## Check we report a warning when the value of e_phoff is so large that
+## e_phoff + e_phnum * e_phentsize > UINT64_MAX.
+# RUN: yaml2obj --docnum=3 -DPHOFF=0xffffffffffffffff %s -o %t.phdr.err3
+# RUN: llvm-readelf --program-headers %t.phdr.err3 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t.phdr.err3 --check-prefix=WARN-PHOFF -DOFF=0xffffffffffffffff
Index: llvm/include/llvm/Object/ELF.h
===================================================================
--- llvm/include/llvm/Object/ELF.h
+++ llvm/include/llvm/Object/ELF.h
@@ -205,16 +205,17 @@
if (getHeader()->e_phnum && getHeader()->e_phentsize != sizeof(Elf_Phdr))
return createError("invalid e_phentsize: " +
Twine(getHeader()->e_phentsize));
- if (getHeader()->e_phoff +
- (getHeader()->e_phnum * getHeader()->e_phentsize) >
- getBufSize())
+
+ uint64_t HeadersSize = (uint64_t)getHeader()->e_phnum * getHeader()->e_phentsize;
+ uint64_t Off = getHeader()->e_phoff;
+ if (Off + HeadersSize < Off || Off + HeadersSize > getBufSize())
return createError("program headers are longer than binary of size " +
Twine(getBufSize()) + ": e_phoff = 0x" +
Twine::utohexstr(getHeader()->e_phoff) +
", e_phnum = " + Twine(getHeader()->e_phnum) +
", e_phentsize = " + Twine(getHeader()->e_phentsize));
- auto *Begin =
- reinterpret_cast<const Elf_Phdr *>(base() + getHeader()->e_phoff);
+
+ auto *Begin = reinterpret_cast<const Elf_Phdr *>(base() + Off);
return makeArrayRef(Begin, Begin + getHeader()->e_phnum);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D83774.277829.patch
Type: text/x-patch
Size: 3857 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200714/6ba2ba6a/attachment.bin>
More information about the llvm-commits
mailing list