https://sourceware.org/bugzilla/show_bug.cgi?id=34779
Bug ID: 34779
Summary: objdump -P data_in_code: Mach-O data-in-code dump
reads past its buffer when datasize is not a multiple
of 8
Product: binutils
Version: 2.47
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: binutils
Assignee: unassigned at sourceware dot org
Reporter: i at mi11ion dot io
Target Milestone: ---
Host: aarch64-apple-darwin
Created attachment 17103
--> https://sourceware.org/bugzilla/attachment.cgi?id=17103&action=edit
dice12.o: Mach-O object, LC_DATA_IN_CODE datasize 12
Environment: GNU objdump (GNU Binutils) 2.47.20260726 and 2.46.0.20260210,
Homebrew binutils on macOS 27.0 (arm64). The code is unchanged on master at
21cffe7c0955c6bdb0c14ded96939d409f3c21f0.
Reproducer: the attached dice12.o (60 bytes) is a Mach-O arm64 MH_OBJECT with
one LC_DATA_IN_CODE load command (dataoff 48, datasize 12). The 12 region bytes
are "40 20 00 00 08 00 04 00 50 20 00 00": one 8-byte data_in_code_entry
(offset 0x2040, length 8, kind 4) and 4 trailing bytes. The file ends at the
region's end.
00000000: cffa edfe 0c00 0001 0000 0000 0100 0000 ................
00000010: 0100 0000 1000 0000 0000 0000 0000 0000 ................
00000020: 2900 0000 1000 0000 3000 0000 0c00 0000 ).......0.......
00000030: 4020 0000 0800 0400 5020 0000 @ ......P ..
Command: objdump -P data_in_code dice12.o
Actual:
offset length kind
0x00002040 0x0008 0x0004 4 bytes jump table
0x00002050 0x0000 0x0000 *UNKNOWN*
Expected: the first entry alone, since 12 bytes hold one 8-byte entry
(<mach-o/loader.h>: "an array of data_in_code_entry entries"; struct
data_in_code_entry { uint32_t offset; uint16_t length; uint16_t kind; }),
optionally with a note that 4 trailing bytes remain. Apple's otool -G prints
one entry.
Analysis: dump_data_in_code in binutils/od-macho.c (line 1398) allocates
datasize bytes and loops for (p = buf; p < buf + cmd->datasize; ), reading an
8-byte entry at p. The condition checks the entry's first byte only; with
datasize 12 the second iteration reads length and kind from buf[12..15], 4
bytes past the allocation. The printed values do not come from the file:
appending aa bb cc dd to the file after the region leaves the output unchanged.
With datasize 4 the tool prints one entry from a region that holds none.
The loop should only read an entry when all 8 of its bytes are inside the
region (and could report any trailing bytes as truncated). The loop in
dump_obj_compact_unwind (line 1998, for (p = content; p < content + size; p +=
sizeof (*e))) has the same form.
--
You are receiving this mail because:
You are on the CC list for the bug.