https://sourceware.org/bugzilla/show_bug.cgi?id=22386
Bug ID: 22386 Summary: Integer overflow in print_debug_frame () Product: binutils Version: 2.30 (HEAD) Status: UNCONFIRMED Severity: normal Priority: P2 Component: binutils Assignee: unassigned at sourceware dot org Reporter: mgcho.minic at gmail dot com Target Milestone: --- Created attachment 10569 --> https://sourceware.org/bugzilla/attachment.cgi?id=10569&action=edit POC file Triggered by "./readelf -w $POC" Tested on Ubuntu 16.04 (x86) An integer overflow is occurred when processing corrupted elf file. ASAN output: ./readelf -w $POC ==14407==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb4803295 at pc 0x081f11ad bp 0xbff83328 sp 0xbff8331c READ of size 1 at 0xb4803295 thread T0 #0 0x81f11ac in display_debug_frames /home/min/fuzzing/src/binutils/binutils-gdb/binutils/dwarf.c:7433:20 #1 0x81c4355 in display_debug_section /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:13399:16 #2 0x8172193 in process_section_contents /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:13485:10 #3 0x81486c0 in process_object /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:18173:9 #4 0x8137e9a in process_file /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:18565:13 #5 0x81367a1 in main /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:18637:11 #6 0xb7507636 in __libc_start_main /build/glibc-KM3i_a/glibc-2.23/csu/../csu/libc-start.c:291 #7 0x805fda7 in _start (/home/min/fuzzing/program/binutils-master-asan/bin/readelf+0x805fda7) 0xb4803295 is located 0 bytes to the right of 341-byte region [0xb4803140,0xb4803295) allocated by thread T0 here: #0 0x81040e4 in __interceptor_malloc (/home/min/fuzzing/program/binutils-master-asan/bin/readelf+0x81040e4) #1 0x81384ba in get_data /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:415:9 #2 0x81347f4 in load_specific_debug_section /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:13200:38 #3 0x81c42c4 in display_debug_section /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:13392:6 #4 0x8172193 in process_section_contents /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:13485:10 #5 0x81486c0 in process_object /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:18173:9 #6 0x8137e9a in process_file /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:18565:13 #7 0x81367a1 in main /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:18637:11 #8 0xb7507636 in __libc_start_main /build/glibc-KM3i_a/glibc-2.23/csu/../csu/libc-start.c:291 SUMMARY: AddressSanitizer: heap-buffer-overflow /home/min/fuzzing/src/binutils/binutils-gdb/binutils/dwarf.c:7433:20 in display_debug_frames Shadow bytes around the buggy address: 0x36900600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x36900610: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x36900620: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 0x36900630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x36900640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x36900650: 00 00[05]fa fa fa fa fa fa fa fa fa fa fa fa fa 0x36900660: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x36900670: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x36900680: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa 0x36900690: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd 0x369006a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==14407==ABORTING The GDB debugging information is as follows: (gdb) r -w $POC (gdb) bt Breakpoint 4, display_debug_frames (section=0x8366c84 <debug_displays+420>, file=0xb5003d80) at dwarf.c:7432 7432 for (i = 0; i < augmentation_data_len; ++i) (gdb) bt #0 display_debug_frames (section=0x8366c84 <debug_displays+420>, file=0xb5003d80) at dwarf.c:7432 #1 0x081c4356 in display_debug_section (shndx=18, section=0xb4602d90, file=0xb5003d80) at readelf.c:13399 #2 0x08172194 in process_section_contents (file=0xb5003d80) at readelf.c:13485 #3 0x081486c1 in process_object (file_name=0xbffff284 "/home/min/Downloads/test", file=0xb5003d80) at readelf.c:18173 #4 0x08137e9b in process_file (file_name=0xbffff284 "/home/min/Downloads/test") at readelf.c:18565 #5 0x081367a2 in main (argc=3, argv=0xbffff064) at readelf.c:18637 (gdb) p start $18 = (unsigned char *) 0x27e6046a "" (gdb) p end $19 = (unsigned char *) 0xb5003994 "" (gdb) p augmentation_data_len $20 = 1927662487 Proposed patch: Check if variable start is overflowed. --- a/home/min/fuzzing/src/binutils/binutils-gdb/binutils/dwarf.c +++ b/home/min/Downloads/dwarf.c @@ -7401,7 +7401,7 @@ display_debug_frames (struct dwarf_section *section, augmentation_data = start; start += augmentation_data_len; /* PR 17512: file: 722-8446-0.004. */ - if (start >= end || ((signed long) augmentation_data_len) < 0) + if (start >= end || ((signed long) augmentation_data_len) < 0 || augmentation_data > start) { warn (_("Corrupt augmentation data length: %lx\n"), augmentation_data_len); Credits: This vulnerability was discovered by Mingi Cho and Taekyoung Kwon of the Information Security Lab, Yonsei University. Please contact mgcho.mi...@gmail.com and taekyo...@yonsei.ac.kr if you need more information about the vulnerability and the lab. -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils