Created attachment 10566 [details] poc of the crash Triggered by "./readelf -a $POC" Tested on Ubuntu 16.04 (x86) I think this is a same bug with PR22307. ASAN output: ./readelf -a $POC ==2365==ERROR: AddressSanitizer: SEGV on unknown address 0xa4c01a64 (pc 0x0824dc7f bp 0xbfffe188 sp 0xbfffdf70 T0) #0 0x824dc7e in byte_get_little_endian /home/min/fuzzing/src/binutils/binutils-gdb/binutils/elfcomm.c:148:16 #1 0x81ced4c in print_gnu_property_note /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:16509:27 #2 0x81cd8ee in print_gnu_note /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:16714:7 #3 0x81c8c6d in process_note /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:17574:12 #4 0x81c6b48 in process_notes_at /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:17736:13 #5 0x81c4da2 in process_corefile_note_segments /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:17766:8 #6 0x81c4b62 in process_note_sections /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:17892:12 #7 0x81722af in process_notes /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:17905:12 #8 0x81486db in process_object /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:18176:9 #9 0x8137e9a in process_file /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:18565:13 #10 0x81367a1 in main /home/min/fuzzing/src/binutils/binutils-gdb/binutils/readelf.c:18637:11 #11 0xb7d7f636 in __libc_start_main /build/glibc-KM3i_a/glibc-2.23/csu/../csu/libc-start.c:291 #12 0x805fda7 in _start (/home/min/fuzzing/program/binutils-master-asan/bin/readelf+0x805fda7) The GDB debugging information is as follows: (gdb) r -a $POC Program received signal SIGSEGV, Segmentation fault. 0x080c055e in byte_get_little_endian (field=0xbfa88 <error: Cannot access memory at address 0xbfa88>, size=4) at elfcomm.c:148 148 return ((unsigned long) (field[0])) (gdb) bt #0 0x080c055e in byte_get_little_endian (field=0xbfa88 <error: Cannot access memory at address 0xbfa88>, size=4) at elfcomm.c:148 #1 0x0808d369 in print_gnu_property_note (pnote=0xbfffeda0) at readelf.c:16509 #2 0x0808c994 in print_gnu_note (pnote=0xbfffeda0) at readelf.c:16714 #3 0x0808a0fe in process_note (pnote=0xbfffeda0, file=0x80fe908) at readelf.c:17574 #4 0x0808990a in process_notes_at (file=0x80fe908, section=0x0, offset=360, length=68) at readelf.c:17736 #5 0x08089353 in process_corefile_note_segments (file=0x80fe908) at readelf.c:17766 #6 0x080892a5 in process_note_sections (file=0x80fe908) at readelf.c:17892 #7 0x0805d3d0 in process_notes (file=0x80fe908) at readelf.c:17905 #8 0x08050dd3 in process_object (file_name=0xbffff2b7 "/tmp/poc", file=0x80fe908) at readelf.c:18176 #9 0x0804a751 in process_file (file_name=0xbffff2b7 "/tmp/poc") at readelf.c:18565 #10 0x08049b81 in main (argc=3, argv=0xbffff0a4) at readelf.c:18637 Proposed patch: Patch as in PR22307. --- a/binutils/readelf.c +++ b/bintuils/readelf.c @@ -16503,15 +16503,23 @@ print_gnu_property_note (Elf_Internal_Note * pnote) return; } - while (1) + while (ptr != ptr_end) { unsigned int j; - unsigned int type = byte_get (ptr, 4); - unsigned int datasz = byte_get (ptr + 4, 4); + unsigned int type; + unsigned int datasz; + if ((size_t) (ptr_end - ptr) < 8) + { + printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz); + break; + } + + type = byte_get (ptr, 4); + datasz = byte_get (ptr + 4, 4); ptr += 8; - if ((ptr + datasz) > ptr_end) + if (datasz > (size_t) (ptr_end - ptr)) { printf (_("<corrupt type (%#x) datasz: %#x>\n"), type, datasz); @@ -16590,21 +16598,12 @@ print_gnu_property_note (Elf_Internal_Note * pnote) next: ptr += ((datasz + (size - 1)) & ~ (size - 1)); - if (ptr == ptr_end) - break; - else - { + if (do_wide) printf (", "); else printf ("\n\t"); - } - if (ptr > (ptr_end - 8)) - { - printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz); - break; - } } printf ("\n"); Credits: This vulnerability was discovered by Mingi Cho and Taekyoung Kwon of the Information Security Lab, Yonsei University. Please contact mgcho.minic@gmail.com and taekyoung@yonsei.ac.kr if you need more information about the vulnerability and the lab.
The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6ab2c4ed51f9c4243691755e1b1d2149c6a426f4 commit 6ab2c4ed51f9c4243691755e1b1d2149c6a426f4 Author: Mingi Cho <mgcho.minic@gmail.com> Date: Thu Nov 2 17:01:08 2017 +0000 Work around integer overflows when readelf is checking for corrupt ELF notes when run on a 32-bit host. PR 22384 * readelf.c (print_gnu_property_note): Improve overflow checks so that they will work on a 32-bit host.
Hi Mingi, Thanks very much for reporting this bug. And thanks again for providing a patch that fixes it. I have checked the patch in, so all should be good now. Cheers Nick