https://sourceware.org/bugzilla/show_bug.cgi?id=34726

            Bug ID: 34726
           Summary: od-macho: OOB read in dump_dyld_info_export_1 (export
                    trie), heap disclosure via objdump -P dyld_info
           Product: binutils
           Version: 2.48 (HEAD)
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: venkatchallaceh at gmail dot com
  Target Milestone: ---

Created attachment 17067
  --> https://sourceware.org/bugzilla/attachment.cgi?id=17067&action=edit
Patch: NUL-terminate the dyld-info buffer and bound the export-trie offset (git
format-patch)

binutils/od-macho.c's dyld-info dumper has an out-of-bounds heap read reachable
via "objdump -P dyld_info <crafted.macho>".

load_and_dump() reads an LC_DYLD_INFO/LC_DYLD_INFO_ONLY sub-blob (e.g. the
export trie) into a heap buffer allocated as exactly the file-controlled size,
with no trailing NUL byte (buf = xmalloc (len); ... bfd_read (buf, len, abfd)).

dump_dyld_info_export_1() then walks the export trie and prints symbol names
straight out of that buffer with unbounded "%s"/strlen (buf[off],
fputs(buf+off), strlen(buf+off)), and recurses into child nodes using an offset
read verbatim from the trie (sub_off), a file-controlled value passed back as
the next "off". Neither the "%s"/strlen reads nor the recursive child offset
are bounded against len, so a crafted Mach-O file makes objdump read past the
end of the heap allocation and print out-of-bounds heap memory to the
operator's terminal (an information leak, not merely a crash).

The sibling dumper dump_dyld_info_bind() already bounds its name walk ("for (;
i < len && buf[i] != 0; i++)"), and the bfd Mach-O string readers read each
field via bfd_mach_o_alloc_and_read() with extra=1 (appends a zeroed NUL); this
dumper's buffer has neither bound.

Reachability: "objdump -P dyld_info <file>" is a standard, documented objdump
invocation; the mach-o target and od-macho dumper are built into any
--enable-targets=all binutils.

Fix (attached): allocate one extra byte and NUL-terminate the buffer in
load_and_dump() (mirroring the extra=1 convention), reject a length that would
overflow the +1, and reject an out-of-range offset at the top of
dump_dyld_info_export_1(). The same patch was/will also be sent to the binutils
mailing list.

AI assistance was used in preparing this report and patch; both were reviewed,
built (objdump builds clean), and verified by a human.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to