Bug 24644 - OOM-Bug in _bfd_archive_64_bit_slurp_armap in bfd/archive64.c
Summary: OOM-Bug in _bfd_archive_64_bit_slurp_armap in bfd/archive64.c
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.33
: P2 normal
Target Milestone: ---
Assignee: Alan Modra
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-06-07 04:14 UTC by Alex Rebert
Modified: 2019-08-07 09:33 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
Input to reproduce (35 bytes, text/plain)
2019-06-07 04:14 UTC, Alex Rebert
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Alex Rebert 2019-06-07 04:14:18 UTC
Created attachment 11819 [details]
Input to reproduce

_bfd_archive_64_bit_slurp_armap reads nsymz from the archive, which is user controller. It then attempts to allocate an amount derived from nsymz, which allows attackers to trigger excessive memory consumption. I'm attaching a minimized input that triggers that issue. You can observe the behavior with `ltrace ./objdump -x ./input 2>&1 | grep malloc` or by compiling objdump with ASAN which produces the following stacktrace:

==39959==ERROR: AddressSanitizer: requested allocation size 0xa0a0a0a0a0a0a18 (0xa0a0a0a0a0a1a18 after adjustments for alignment, red zones etc.) exceeds maximum supported size of 0x10000000000 (thread T0)
    #0 0x49665d in __interceptor_malloc /b/swarming/w/ir/k/src/third_party/llvm/compiler-rt/lib/asan/asan_malloc_linux.cc:145:3
    #1 0x1148578 in _objalloc_alloc /fas/apr/binutils-gdb/build-libfuzzer/libiberty/../../libiberty/objalloc.c:143:22
    #2 0x7f91d9 in bfd_alloc /fas/apr/binutils-gdb/build-libfuzzer/bfd/../../bfd/opncls.c:949:9
    #3 0x7f8381 in bfd_zalloc /fas/apr/binutils-gdb/build-libfuzzer/bfd/../../bfd/opncls.c:998:9
    #4 0x10c1636 in _bfd_archive_64_bit_slurp_armap /fas/apr/binutils-gdb/build-libfuzzer/bfd/../../bfd/archive64.c:98:39
    #5 0x7d90c6 in bfd_slurp_armap /fas/apr/binutils-gdb/build-libfuzzer/bfd/../../bfd/archive.c:1149:14
    #6 0x7d8a84 in bfd_generic_archive_p /fas/apr/binutils-gdb/build-libfuzzer/bfd/../../bfd/archive.c:875:8
    #7 0x7f0da6 in bfd_check_format_matches /fas/apr/binutils-gdb/build-libfuzzer/bfd/../../bfd/format.c:315:14

- binutils version: commit 12efd68d159444ad8dfe24e49965a228ba980b86 (Wed Jun 5 2019)
- OS: Ubuntu 18.04.2, running in a docker container on Mac OS
- Linux 4.9.125-linuxkit
- clang version 9.0.0


Found using ForAllSecure's Mayhem.
Comment 1 Alan Modra 2019-06-07 05:41:55 UTC
Out of memory is uninteresting unless it is triggered by a bug in binutils code that incorrectly calculates the amount of memory needed.
Comment 2 Alex Rebert 2019-06-07 21:32:11 UTC
Oops. Sorry about that. I saw https://sourceware.org/bugzilla/show_bug.cgi?id=23361 and thought you were interested in those.

FWIW, there are a few overflows in there, and the overflow checks don't catch them all. I haven't been able to make it crash yet, but I have an input that leads to calling bfd_bread on a small buffer with a very large size. Happy to upload it if you're interested in it.

Details: When parsed_size=-1 and nsymz=2, the function allocates a 8-byte symdefs array, while stringsize is 18446744073709551591). Since bfd_read calls cache_bread, which takes a signed size which ends up being negative, no overflow happens.
Comment 3 Sourceware Commits 2019-08-07 09:32:09 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=97b031c5d6d42ff2b1758a8a8c332cb44ba9c06f

commit 97b031c5d6d42ff2b1758a8a8c332cb44ba9c06f
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Aug 7 18:53:09 2019 +0930

    PR24644, OOM-Bug in _bfd_archive_64_bit_slurp_armap
    
    	PR 24644
    	* archive64.c (_bfd_archive_64_bit_slurp_armap): Properly check
    	for overflow in expressions involving nsymz.
Comment 4 Alan Modra 2019-08-07 09:33:19 UTC
Patch applied to fix the overflow checking.