Skip to content

Commit cc945e4

Browse files
authored
[MachO] Loosen boundary check for reading export trie nodes (#96705)
The design of the export trie in macho's is that each node has a variable length payload. When reading nodes, it should be an error if reading the uleb128 puts you beyond the stated node size but not when the stated size goes beyond the known part that was read. resolves: rdar://130310832 This was primarily authored by Nick Kledzik, I added/cleaned up the test cases.
1 parent bd7b162 commit cc945e4

File tree

4 files changed

+374
-4
lines changed

4 files changed

+374
-4
lines changed

llvm/lib/Object/MachOObjectFile.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3104,7 +3104,7 @@ void ExportEntry::pushNode(uint64_t offset) {
31043104
}
31053105
}
31063106
}
3107-
if(ExportStart + ExportInfoSize != State.Current) {
3107+
if (ExportStart + ExportInfoSize < State.Current) {
31083108
*E = malformedError(
31093109
"inconsistent export info size: 0x" +
31103110
Twine::utohexstr(ExportInfoSize) + " where actual size was: 0x" +
Binary file not shown.

llvm/test/tools/llvm-objdump/MachO/bad-trie.test

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,3 @@ LOOP_OF_CHILDERN: macho-trie-node-loop': truncated or malformed object (loop in
3030

3131
RUN: not llvm-objdump --macho --exports-trie %p/Inputs/macho-trie-bad-library-ordinal 2>&1 | FileCheck --check-prefix BAD_LIBRARY_ORDINAL %s
3232
BAD_LIBRARY_ORDINAL: macho-trie-bad-library-ordinal': truncated or malformed object (bad library ordinal: 69 (max 3) in export trie data at node: 0x33)
33-
34-
RUN: not llvm-objdump --macho --exports-trie %p/Inputs/macho-inconsistent-export 2>&1 | FileCheck --check-prefix INCONSISTENT_EXPORT_SIZE %s
35-
INCONSISTENT_EXPORT_SIZE: macho-inconsistent-export': truncated or malformed object (inconsistent export info size: 0x9 where actual size was: 0x5 in export trie data at node: 0x53)
Lines changed: 373 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,373 @@
1+
; RUN: rm -rf %t
2+
; RUN: split-file %s %t
3+
; RUN: yaml2obj %t/payload-extended.yaml -o %t/payload-extended.dylib
4+
; RUN: llvm-objdump --macho --exports-trie %t/payload-extended.dylib 2>&1 | FileCheck %s
5+
6+
; CHECK: 0x00003FB0 _foo
7+
8+
; RUN: yaml2obj %t/payload-truncated.yaml -o %t/payload-truncated.dylib
9+
; RUN: not llvm-objdump --macho --exports-trie %t/payload-truncated.dylib 2>&1 | FileCheck %s --check-prefix=WRONG_SIZE
10+
11+
; WRONG_SIZE: truncated or malformed object (inconsistent export info size: 0x2 where actual size was: 0x3 in export trie data at node: 0x8)
12+
13+
# Yaml was manually crafted to have an export trie with a node entry
14+
# where it's payload is larger than the size needed to read it.
15+
;--- payload-extended.yaml
16+
--- !mach-o
17+
FileHeader:
18+
magic: 0xFEEDFACF
19+
cputype: 0x100000C
20+
cpusubtype: 0x0
21+
filetype: 0x6
22+
ncmds: 13
23+
sizeofcmds: 680
24+
flags: 0x100085
25+
reserved: 0x0
26+
LoadCommands:
27+
- cmd: LC_SEGMENT_64
28+
cmdsize: 232
29+
segname: __TEXT
30+
vmaddr: 0
31+
vmsize: 16384
32+
fileoff: 0
33+
filesize: 16384
34+
maxprot: 5
35+
initprot: 5
36+
nsects: 2
37+
flags: 0
38+
Sections:
39+
- sectname: __text
40+
segname: __TEXT
41+
addr: 0x3FB0
42+
size: 8
43+
offset: 0x3FB0
44+
align: 2
45+
reloff: 0x0
46+
nreloc: 0
47+
flags: 0x80000400
48+
reserved1: 0x0
49+
reserved2: 0x0
50+
reserved3: 0x0
51+
content: 20008052C0035FD6
52+
- sectname: __unwind_info
53+
segname: __TEXT
54+
addr: 0x3FB8
55+
size: 72
56+
offset: 0x3FB8
57+
align: 2
58+
reloff: 0x0
59+
nreloc: 0
60+
flags: 0x0
61+
reserved1: 0x0
62+
reserved2: 0x0
63+
reserved3: 0x0
64+
content: 010000001C000000000000001C000000000000001C00000002000000B03F00003400000034000000B93F00000000000034000000030000000C000100100001000000000000000002
65+
- cmd: LC_SEGMENT_64
66+
cmdsize: 72
67+
segname: __LINKEDIT
68+
vmaddr: 16384
69+
vmsize: 16384
70+
fileoff: 16384
71+
filesize: 361
72+
maxprot: 1
73+
initprot: 1
74+
nsects: 0
75+
flags: 0
76+
- cmd: LC_ID_DYLIB
77+
cmdsize: 48
78+
dylib:
79+
name: 24
80+
timestamp: 1
81+
current_version: 0
82+
compatibility_version: 0
83+
Content: '@rpath/libfoo.dylib'
84+
ZeroPadBytes: 5
85+
- cmd: LC_DYLD_INFO_ONLY
86+
cmdsize: 48
87+
rebase_off: 0
88+
rebase_size: 0
89+
bind_off: 0
90+
bind_size: 0
91+
weak_bind_off: 0
92+
weak_bind_size: 0
93+
lazy_bind_off: 0
94+
lazy_bind_size: 0
95+
export_off: 16384
96+
export_size: 16
97+
- cmd: LC_SYMTAB
98+
cmdsize: 24
99+
symoff: 16408
100+
nsyms: 2
101+
stroff: 16440
102+
strsize: 24
103+
- cmd: LC_DYSYMTAB
104+
cmdsize: 80
105+
ilocalsym: 0
106+
nlocalsym: 0
107+
iextdefsym: 0
108+
nextdefsym: 1
109+
iundefsym: 1
110+
nundefsym: 1
111+
tocoff: 0
112+
ntoc: 0
113+
modtaboff: 0
114+
nmodtab: 0
115+
extrefsymoff: 0
116+
nextrefsyms: 0
117+
indirectsymoff: 0
118+
nindirectsyms: 0
119+
extreloff: 0
120+
nextrel: 0
121+
locreloff: 0
122+
nlocrel: 0
123+
- cmd: LC_UUID
124+
cmdsize: 24
125+
uuid: A2CF51D8-828B-3E0F-B8FA-0DF9C5D1C91A
126+
- cmd: LC_BUILD_VERSION
127+
cmdsize: 32
128+
platform: 1
129+
minos: 721664
130+
sdk: 917504
131+
ntools: 1
132+
Tools:
133+
- tool: 3
134+
version: 59441152
135+
- cmd: LC_SOURCE_VERSION
136+
cmdsize: 16
137+
version: 0
138+
- cmd: LC_LOAD_DYLIB
139+
cmdsize: 56
140+
dylib:
141+
name: 24
142+
timestamp: 2
143+
current_version: 87556096
144+
compatibility_version: 65536
145+
Content: '/usr/lib/libSystem.B.dylib'
146+
ZeroPadBytes: 6
147+
- cmd: LC_FUNCTION_STARTS
148+
cmdsize: 16
149+
dataoff: 16400
150+
datasize: 8
151+
- cmd: LC_DATA_IN_CODE
152+
cmdsize: 16
153+
dataoff: 16408
154+
datasize: 0
155+
- cmd: LC_CODE_SIGNATURE
156+
cmdsize: 16
157+
dataoff: 16464
158+
datasize: 281
159+
LinkEditData:
160+
ExportTrie:
161+
TerminalSize: 0
162+
NodeOffset: 0
163+
Name: ''
164+
Flags: 0x0
165+
Address: 0x0
166+
Other: 0x0
167+
ImportName: ''
168+
Children:
169+
- TerminalSize: 4
170+
NodeOffset: 8
171+
Name: _foo
172+
Flags: 0x0
173+
Address: 0x3FB0
174+
Other: 0x0
175+
ImportName: ''
176+
NameList:
177+
- n_strx: 2
178+
n_type: 0xF
179+
n_sect: 1
180+
n_desc: 0
181+
n_value: 16304
182+
- n_strx: 7
183+
n_type: 0x1
184+
n_sect: 0
185+
n_desc: 256
186+
n_value: 0
187+
StringTable:
188+
- ' '
189+
- _foo
190+
- dyld_stub_binder
191+
FunctionStarts: [ 0x3FB0 ]
192+
...
193+
194+
# Yaml was manually crafted to have an export trie with a node entry
195+
# where it's payload is smaller than the size needed to read it.
196+
;--- payload-truncated.yaml
197+
--- !mach-o
198+
FileHeader:
199+
magic: 0xFEEDFACF
200+
cputype: 0x100000C
201+
cpusubtype: 0x0
202+
filetype: 0x6
203+
ncmds: 13
204+
sizeofcmds: 680
205+
flags: 0x100085
206+
reserved: 0x0
207+
LoadCommands:
208+
- cmd: LC_SEGMENT_64
209+
cmdsize: 232
210+
segname: __TEXT
211+
vmaddr: 0
212+
vmsize: 16384
213+
fileoff: 0
214+
filesize: 16384
215+
maxprot: 5
216+
initprot: 5
217+
nsects: 2
218+
flags: 0
219+
Sections:
220+
- sectname: __text
221+
segname: __TEXT
222+
addr: 0x3FB0
223+
size: 8
224+
offset: 0x3FB0
225+
align: 2
226+
reloff: 0x0
227+
nreloc: 0
228+
flags: 0x80000400
229+
reserved1: 0x0
230+
reserved2: 0x0
231+
reserved3: 0x0
232+
content: 20008052C0035FD6
233+
- sectname: __unwind_info
234+
segname: __TEXT
235+
addr: 0x3FB8
236+
size: 72
237+
offset: 0x3FB8
238+
align: 2
239+
reloff: 0x0
240+
nreloc: 0
241+
flags: 0x0
242+
reserved1: 0x0
243+
reserved2: 0x0
244+
reserved3: 0x0
245+
content: 010000001C000000000000001C000000000000001C00000002000000B03F00003400000034000000B93F00000000000034000000030000000C000100100001000000000000000002
246+
- cmd: LC_SEGMENT_64
247+
cmdsize: 72
248+
segname: __LINKEDIT
249+
vmaddr: 16384
250+
vmsize: 16384
251+
fileoff: 16384
252+
filesize: 361
253+
maxprot: 1
254+
initprot: 1
255+
nsects: 0
256+
flags: 0
257+
- cmd: LC_ID_DYLIB
258+
cmdsize: 48
259+
dylib:
260+
name: 24
261+
timestamp: 1
262+
current_version: 0
263+
compatibility_version: 0
264+
Content: '@rpath/libfoo.dylib'
265+
ZeroPadBytes: 5
266+
- cmd: LC_DYLD_INFO_ONLY
267+
cmdsize: 48
268+
rebase_off: 0
269+
rebase_size: 0
270+
bind_off: 0
271+
bind_size: 0
272+
weak_bind_off: 0
273+
weak_bind_size: 0
274+
lazy_bind_off: 0
275+
lazy_bind_size: 0
276+
export_off: 16384
277+
export_size: 16
278+
- cmd: LC_SYMTAB
279+
cmdsize: 24
280+
symoff: 16408
281+
nsyms: 2
282+
stroff: 16440
283+
strsize: 24
284+
- cmd: LC_DYSYMTAB
285+
cmdsize: 80
286+
ilocalsym: 0
287+
nlocalsym: 0
288+
iextdefsym: 0
289+
nextdefsym: 1
290+
iundefsym: 1
291+
nundefsym: 1
292+
tocoff: 0
293+
ntoc: 0
294+
modtaboff: 0
295+
nmodtab: 0
296+
extrefsymoff: 0
297+
nextrefsyms: 0
298+
indirectsymoff: 0
299+
nindirectsyms: 0
300+
extreloff: 0
301+
nextrel: 0
302+
locreloff: 0
303+
nlocrel: 0
304+
- cmd: LC_UUID
305+
cmdsize: 24
306+
uuid: A2CF51D8-828B-3E0F-B8FA-0DF9C5D1C91A
307+
- cmd: LC_BUILD_VERSION
308+
cmdsize: 32
309+
platform: 1
310+
minos: 721664
311+
sdk: 917504
312+
ntools: 1
313+
Tools:
314+
- tool: 3
315+
version: 59441152
316+
- cmd: LC_SOURCE_VERSION
317+
cmdsize: 16
318+
version: 0
319+
- cmd: LC_LOAD_DYLIB
320+
cmdsize: 56
321+
dylib:
322+
name: 24
323+
timestamp: 2
324+
current_version: 87556096
325+
compatibility_version: 65536
326+
Content: '/usr/lib/libSystem.B.dylib'
327+
ZeroPadBytes: 6
328+
- cmd: LC_FUNCTION_STARTS
329+
cmdsize: 16
330+
dataoff: 16400
331+
datasize: 8
332+
- cmd: LC_DATA_IN_CODE
333+
cmdsize: 16
334+
dataoff: 16408
335+
datasize: 0
336+
- cmd: LC_CODE_SIGNATURE
337+
cmdsize: 16
338+
dataoff: 16464
339+
datasize: 281
340+
LinkEditData:
341+
ExportTrie:
342+
TerminalSize: 0
343+
NodeOffset: 0
344+
Name: ''
345+
Flags: 0x0
346+
Address: 0x0
347+
Other: 0x0
348+
ImportName: ''
349+
Children:
350+
- TerminalSize: 2
351+
NodeOffset: 8
352+
Name: _foo
353+
Flags: 0x0
354+
Address: 0x3FB0
355+
Other: 0x0
356+
ImportName: ''
357+
NameList:
358+
- n_strx: 2
359+
n_type: 0xF
360+
n_sect: 1
361+
n_desc: 0
362+
n_value: 16304
363+
- n_strx: 7
364+
n_type: 0x1
365+
n_sect: 0
366+
n_desc: 256
367+
n_value: 0
368+
StringTable:
369+
- ' '
370+
- _foo
371+
- dyld_stub_binder
372+
FunctionStarts: [ 0x3FB0 ]
373+
...

0 commit comments

Comments
 (0)