Skip to content

Commit b209b9e

Browse files
committed
[COFF] Don't reject executables with data directories pointing outside of provided data
Before bb94611, we didn't check that the sections in the COFF executable actually contained enough raw data, when looking up what section contains tables pointed to by the data directories. That commit added checking, to avoid setting a pointer that points out of bounds - by rejecting such executables. It turns out that some binaries (e.g.g a "helper.exe" provided by NSIS) contains a base relocation table data directory that points into the wrong section. It points inside the virtual address space allocated for that section, but the section contains much less raw data, and the table points outside of the provided raw data. No longer reject such binaries (to let tools operate on them and inspect them), but don't set the table pointers (so that when printing e.g. base relocations, we don't print anything). This should fix the regression pointed out in https://reviews.llvm.org/D126898#3565834. Differential Revision: https://reviews.llvm.org/D127345
1 parent c60c13f commit b209b9e

File tree

3 files changed

+103
-10
lines changed

3 files changed

+103
-10
lines changed

llvm/lib/Object/COFFObjectFile.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -483,18 +483,12 @@ Error COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res,
483483
// fail, otherwise it will be impossible to use this object as debug info
484484
// in LLDB. Return SectionStrippedError here so that
485485
// COFFObjectFile::initialize can ignore the error.
486-
if (Section->SizeOfRawData == 0)
487-
return make_error<SectionStrippedError>();
486+
// Somewhat common binaries may have RVAs pointing outside of the
487+
// provided raw data. Instead of rejecting the binaries, just
488+
// treat the section as stripped for these purposes.
488489
if (Section->SizeOfRawData < Section->VirtualSize &&
489490
Addr >= SectionStart + Section->SizeOfRawData) {
490-
if (ErrorContext)
491-
return createStringError(object_error::parse_failed,
492-
"RVA 0x%" PRIx32
493-
" for %s found but data is incomplete",
494-
Addr, ErrorContext);
495-
return createStringError(
496-
object_error::parse_failed,
497-
"RVA 0x%" PRIx32 " found but data is incomplete", Addr);
491+
return make_error<SectionStrippedError>();
498492
}
499493
uint32_t Offset = Addr - SectionStart;
500494
Res = reinterpret_cast<uintptr_t>(base()) + Section->PointerToRawData +
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
--- !COFF
2+
OptionalHeader:
3+
AddressOfEntryPoint: 4144
4+
ImageBase: 1073741824
5+
SectionAlignment: 4096
6+
FileAlignment: 512
7+
MajorOperatingSystemVersion: 6
8+
MinorOperatingSystemVersion: 0
9+
MajorImageVersion: 0
10+
MinorImageVersion: 0
11+
MajorSubsystemVersion: 6
12+
MinorSubsystemVersion: 0
13+
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
14+
DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ]
15+
SizeOfStackReserve: 1048576
16+
SizeOfStackCommit: 4096
17+
SizeOfHeapReserve: 1048576
18+
SizeOfHeapCommit: 4096
19+
ExportTable:
20+
RelativeVirtualAddress: 0
21+
Size: 0
22+
ImportTable:
23+
RelativeVirtualAddress: 0
24+
Size: 0
25+
ResourceTable:
26+
RelativeVirtualAddress: 0
27+
Size: 0
28+
ExceptionTable:
29+
RelativeVirtualAddress: 0
30+
Size: 0
31+
CertificateTable:
32+
RelativeVirtualAddress: 0
33+
Size: 0
34+
BaseRelocationTable:
35+
RelativeVirtualAddress: 14288
36+
Size: 32
37+
Debug:
38+
RelativeVirtualAddress: 0
39+
Size: 0
40+
Architecture:
41+
RelativeVirtualAddress: 0
42+
Size: 0
43+
GlobalPtr:
44+
RelativeVirtualAddress: 0
45+
Size: 0
46+
TlsTable:
47+
RelativeVirtualAddress: 0
48+
Size: 0
49+
LoadConfigTable:
50+
RelativeVirtualAddress: 0
51+
Size: 0
52+
BoundImport:
53+
RelativeVirtualAddress: 0
54+
Size: 0
55+
IAT:
56+
RelativeVirtualAddress: 0
57+
Size: 0
58+
DelayImportDescriptor:
59+
RelativeVirtualAddress: 0
60+
Size: 0
61+
ClrRuntimeHeader:
62+
RelativeVirtualAddress: 0
63+
Size: 0
64+
header:
65+
Machine: IMAGE_FILE_MACHINE_AMD64
66+
Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ]
67+
sections:
68+
- Name: .text
69+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
70+
VirtualAddress: 4096
71+
VirtualSize: 87
72+
SectionData: 50894C24048B0DF51F0000034C240489C859C3662E0F1F8400000000000F1F00C3662E0F1F8400000000000F1F440000554883EC30488D6C2430E8E1FFFFFFC745FC00000000B902000000E8B0FFFFFF904883C4305DC3
73+
- Name: .rdata
74+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
75+
VirtualAddress: 8192
76+
VirtualSize: 20
77+
SectionData: 0101010001020000010A03350A03055201500000
78+
- Name: .data
79+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
80+
VirtualAddress: 12288
81+
VirtualSize: 3000
82+
SectionData: '01000000'
83+
- Name: .reloc
84+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
85+
VirtualAddress: 16384
86+
VirtualSize: 32
87+
SectionData: '4DB3FFFF3090F9FF606DA6FFC69393FF'
88+
symbols: []
89+
...
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
; Check an executable, where the baes relocation data directory points into
2+
; a section (within the range specified by VirtualSize), but outside of the
3+
; raw data provided in the executable. Make sure that we don't error out on
4+
; the executable - but we don't try to print any base relocs (as their data
5+
; is missing).
6+
7+
RUN: yaml2obj %p/Inputs/COFF/data-dir-out-of-bounds.yaml | llvm-readobj --coff-basereloc - | FileCheck %s
8+
9+
CHECK: BaseReloc [
10+
CHECK-NEXT: ]

0 commit comments

Comments
 (0)