Bug 22361 - Memory Allocation Error stemming from a Conditional jump dependant on an uninitialized value in process_archive (within readelf.c)
Summary: Memory Allocation Error stemming from a Conditional jump dependant on an unin...
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.29
: P2 normal
Target Milestone: 2.30
Assignee: Alan Modra
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-10-27 19:49 UTC by Kirit Sankar Gupta
Modified: 2017-10-28 11:48 UTC (History)
0 users

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


Attachments
Crashing file sample (331 bytes, application/x-archive)
2017-10-27 19:49 UTC, Kirit Sankar Gupta
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Kirit Sankar Gupta 2017-10-27 19:49:31 UTC
Created attachment 10559 [details]
Crashing file sample

Invoking readelf on a specially crafted file results in an attempt to allocate a massive amount of memory, due to a conditional jump which depends on an uninitialized variable. Running Memcheck gives the following output:

==28540== Conditional jump or move depends on uninitialised value(s)
==28540==    at 0x4E7A21B: ____strtoul_l_internal (strtol_l.c:434)
==28540==    by 0x159F6C: setup_archive (elfcomm.c:658)
==28540==    by 0x1407C6: process_archive (readelf.c:18196)
==28540==    by 0x10F5BC: process_file (readelf.c:18460)
==28540==    by 0x10F5BC: main (readelf.c:18544)
==28540==  Uninitialised value was created by a stack allocation
==28540==    at 0x14070F: process_archive (readelf.c:18172)

The hexdump of the input file is:

0000000 3c21 7261 6863 0a3e 2f2f 2020 2020 2020
0000010 2020 2020 2020 2020 2030 2020 2020 2020
0000020 2020 2020 2030 2020 2020 2030 2020 2020
0000030 2030 2020 2020 2020 3731 3230 3232 3232
0000040 3232 3232 3232 3232 3232 3232 3232 3232
*
0000100 3232 4d32 3232 3232 3232 322d 3232 3232
0000110 3232 3232 3232 3232 3232 3232 3232 3232
0000120 3232 1032 4c74 6269 4c56 6269 3356 7453
0000130 7461 6f43 6e75 0074 6478 5f72 7547 7365
0000140 4c74 6269 3356 7954 6570 6449 0073 6478
0000150 5f72 6564 2072 6874 2065 6574 6d72 2073
0000160 666f 740a 6568 4720 554e 4720 6e65 7265
0000170 6c63 5020 6275 696c 2063 694c 6563 736e
0000180 2065 6576 7372 6f69 206e 2033 726f 2820
0000190 7461 7920 756f 2072 706f 6974 6e6f 2029
00001a0 4761 6575 7473 694c 5662 5333 6174 0074
00001b0 6478 5f72 7547 7365 7473 694c 4962 636f
00001c0 6c74 6449 7800 7264 475f 6575 7473 694c
00001d0 4962 636f 6c74 7441 6d6f 6369 7055 0064
00001e0 0000 0004 0000 001c 0000 0058 0000 0000
00001f0 0000 0004 1e00 03e8 0000 e551 6474 0006
0000200 0000 0000 001c 0000 0058 0000 0000 0000
0000210 0004 0000 03e8 0000 e551 6474 fa06 ffff
0000220 00ff 0000 0000 0000 0000 0000 0000 0000
0000230 0000 0000 0000 000a 0000 0100 0000 2000
0000240 7469 7520 646e 7265 7420 6568 7420 7265
0000250 736d 6f20 0a66 6874 2065 4e47 2055 6547
0000260 656e 6172 206c 7550 6c62 6369 4c20 6369
0000270 6e65 6573 7620 7265 6973 6e6f 3320 6f20
0000280 2072 6128 2074 6f79 7275 6f20 7470 6f69
0000290 296e 6120 796e 6c20 7461 7265 7620 7265
00002a0 6973 6e6f 0a2e 6854 7369 7020 6f72 7267
00002b0 6d61 6820 7361 ff20 51ff 6c6f 7475 6c65
00002c0 2079 6f6e e21f 0010 0000 0300 1000 0000
00002d0 0000 0000 0000 0000 0000 0000 0000 0000
00002e0 0000 0300 1c00 0000 0000 0000 0000 0000
00002f0 0000 0000 0000 b800 0000 1000 0000 0000
0000300 0000 0000 0000 0000 0000 0000 0600 6600
0000310 0001 1600 0000 0000 0000 0000 0000 0000
0000320 0000 0000 0000 0900 0001 1000 0000 0000
0000330 0000 0000 0000 0000 0000 0000 0000 3200
0000340 0000 1000 0000 0000 0000 0000 0500 ffff
0000350 0005 0000 0000 5800 0000 1000 0000 0000
0000360 0000 0000 0000 0000 0000 0000 0000 3e00
0000370 0000 1000 0000 0000 0000 0000 0000 0019
0000380 fc00 0000 0000 b200 0001 1000 0000 0000
0000390 0000 0000 0000 0000 0000 0000 0000 0f00
00003a0 0000 1000 0000 0000 0000 0000 0000 0000
00003b0 0000 0000 0000 2d00 0000 0000 0010 0000
*
00003c3

Running with AddressSanitizer crashes with the following information:

==16021==ERROR: AddressSanitizer failed to allocate 0x27a2092000 (170222231552) bytes of LargeMmapAllocator (error code: 12)
==16021==Process memory map follows:
        0x000000400000-0x0000006de000   /home/ksg/testbed/binutils-2.29/binutils/readelf
        0x0000008de000-0x0000008df000   /home/ksg/testbed/binutils-2.29/binutils/readelf
        0x0000008df000-0x00000095c000   /home/ksg/testbed/binutils-2.29/binutils/readelf


==16021==AddressSanitizer CHECK failed: /build/llvm-toolchain-3.9-BMQCTD/llvm-toolchain-3.9-3.9.1/projects/compiler-rt/lib/sanitizer_common/sanitizer_common.cc:120 "((0 && "unable to mmap")) != (0)" (0x0, 0x0)
    #0 0x4d5785 in __asan::AsanCheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/home/ksg/testbed/binutils-2.29/binutils/readelf+0x4d5785)
    #1 0x4efe95 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/home/ksg/testbed/binutils-2.29/binutils/readelf+0x4efe95)
    #2 0x4df5c2 in __sanitizer::ReportMmapFailureAndDie(unsigned long, char const*, char const*, int, bool) (/home/ksg/testbed/binutils-2.29/binutils/readelf+0x4df5c2)
    #3 0x4e9535 in __sanitizer::MmapOrDie(unsigned long, char const*, bool) (/home/ksg/testbed/binutils-2.29/binutils/readelf+0x4e9535)
    #4 0x4237fd in __asan::asan_malloc(unsigned long, __sanitizer::BufferedStackTrace*) (/home/ksg/testbed/binutils-2.29/binutils/readelf+0x4237fd)
    #5 0x4cb87b in malloc (/home/ksg/testbed/binutils-2.29/binutils/readelf+0x4cb87b)
    #6 0x5c4c00 in setup_archive /home/ksg/testbed/binutils-2.29/binutils/elfcomm.c:677:34
    #7 0x50fca4 in process_archive /home/ksg/testbed/binutils-2.29/binutils/readelf.c:18196:7
    #8 0x5065d5 in process_file /home/ksg/testbed/binutils-2.29/binutils/readelf.c:18455:13
    #9 0x5065d5 in main /home/ksg/testbed/binutils-2.29/binutils/readelf.c:18544
    #10 0x7f1e904861c0 in __libc_start_main /build/glibc-CxtIbX/glibc-2.26/csu/../csu/libc-start.c:308
    #11 0x41c2d9 in _start (/home/ksg/testbed/binutils-2.29/binutils/readelf+0x41c2d9)

Will post further updates on what I think might be causing the "uninitialized value" to be returned from the process_archive method in readelf.c
Comment 1 Kirit Sankar Gupta 2017-10-27 19:53:11 UTC
Debug info:

Binutils Version: 2.29
Readelf Version: 2.29
OS: Ubuntu 17.10
Compiler: gcc 7.2.0 / clang 4.0.1-6 (tested with both)
Target: x86_64-linux-gnu
Comment 2 cvs-commit@gcc.gnu.org 2017-10-28 11:47:14 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit d91f0b20e561e326ee91a09a76206257bde8438b
Author: Alan Modra <amodra@gmail.com>
Date:   Sat Oct 28 21:31:16 2017 +1030

    PR22361 readelf buffer overflow on fuzzed archive header
    
    	PR 22361
    	* readelf.c (process_archive_index_and_symbols): Ensure ar_size
    	field is zero terminated for strtoul.
    	(setup_archive, get_archive_member_name): Likewise.
Comment 3 Alan Modra 2017-10-28 11:48:04 UTC
Fixed