Created attachment 10218 [details] Triggered by "nm -n POC1" The debugging information is as follows: $./nm -n POC1 ==94585==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffffffde3f at pc 0x0000005432ca bp 0x7fffffffdcd0 sp 0x7fffffffdcc8 READ of size 1 at 0x7fffffffde3f thread T0 #0 0x5432c9 (/home/icy/real/binutils-2.28-asan/install/bin/nm+0x5432c9) #1 0x51608a (/home/icy/real/binutils-2.28-asan/install/bin/nm+0x51608a) #2 0x4ec316 (/home/icy/real/binutils-2.28-asan/install/bin/nm+0x4ec316) #3 0x4eb734 (/home/icy/real/binutils-2.28-asan/install/bin/nm+0x4eb734) #4 0x7ffff6ee582f (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) #5 0x4194b8 (/home/icy/real/binutils-2.28-asan/install/bin/nm+0x4194b8) Address 0x7fffffffde3f is located in stack of thread T0 at offset 351 in frame #0 0x53fe8f (/home/icy/real/binutils-2.28-asan/install/bin/nm+0x53fe8f) This frame has 3 object(s): [32, 49) 'sym.i.i' [96, 351) 'src.i' <== Memory access at offset 351 overflows this variable [416, 420) 'b' HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-buffer-overflow (/home/icy/real/binutils-2.28-asan/install/bin/nm+0x5432c9) Shadow bytes around the buggy address: 0x10007fff7b70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7b90: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 0x10007fff7ba0: 00 00 01 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 0x10007fff7bb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x10007fff7bc0: 00 00 00 00 00 00 00[07]f2 f2 f2 f2 f2 f2 f2 f2 0x10007fff7bd0: 04 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7be0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x10007fff7bf0: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00 0x10007fff7c00: 00 00 00 00 00 00 00 00 00 f3 f3 f3 f3 f3 f3 f3 0x10007fff7c10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 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 ==94585==ABORTING [Inferior 1 (process 94585) exited with code 01] Program crash at line tekhex.c:. After multiple cycles, pointer src will point to NULL, macro ISHEX(x) failed to access this NULL value, which cause that problem . tekhex.c: 93 #define ISHEX(x) hex_p(x) ... 269 static bfd_boolean 270 getvalue (char **srcp, bfd_vma *valuep, char * endp) 271 { 272 char *src = *srcp; 273 bfd_vma value = 0; 274 unsigned int len; 275 276 if (!ISHEX (*src)) 277 return FALSE; 278 279 len = hex_value (*src++); libiberty.h: 381 #define _hex_bad 99 382 extern const unsigned char _hex_value[_hex_array_size]; 383 extern void hex_init (void); 384 #define hex_p(c) (hex_value (c) != _hex_bad) 385 /* If you change this, note well: Some code relies on side effects in 386 the argument being performed exactly once. */ 387 #define hex_value(c) ((unsigned int) _hex_value[(unsigned char) (c)]) the gdb debugging infomation is as follows: (gdb)set args -n POC1 (gdb)r ... (gdb) p src $24 = 0x7fffffffde3f "" (gdb) n 491 if (!getvalue (&src, &val, src_end)) (gdb) s getvalue (endp=<optimized out>, srcp=<optimized out>, valuep=<optimized out>) at tekhex.c:276 276 if (!ISHEX (*src)) (gdb) s Program received signal SIGSEGV, Segmentation fault. 0xffffffffcd4c2e50 in ?? () (gdb) bt #0 0xffffffffcd4c2e50 in ?? () #1 0x00000000005432ca in getvalue (endp=<optimized out>, srcp=<optimized out>, valuep=<optimized out>) at tekhex.c:276 #2 first_phase (abfd=0x61200000bec0, src=<optimized out>, src_end=<optimized out>, type=<optimized out>) at tekhex.c:491 #3 pass_over (abfd=<optimized out>, func=<optimized out>) at tekhex.c:550 #4 tekhex_object_p (abfd=<optimized out>) at tekhex.c:615 #5 0x000000000051608b in bfd_check_format_matches (abfd=<optimized out>, format=<optimized out>, matching=<optimized out>) at format.c:311 #6 0x00000000004ec317 in display_file (filename=0x7fffffffe7a9 "id:000025,sig:06,src:000931,op:arith8,pos:245,val:+19") at nm.c:1315 #7 0x00000000004eb735 in main (argc=<optimized out>, argv=<optimized out>) at nm.c:1793 (gdb) Credits: This vulnerability is detected by team OWL337, with our custom fuzzer collAFL. Please contact ganshuitao@gmail.com and chaoz@tsinghua.edu.cn if you need more info about the team, the tool or the vulnerability.
The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=04e15b4a9462cb1ae819e878a6009829aab8020b commit 04e15b4a9462cb1ae819e878a6009829aab8020b Author: Nick Clifton <nickc@redhat.com> Date: Mon Jun 26 15:46:34 2017 +0100 Fix address violation parsing a corrupt texhex format file. PR binutils/21670 * tekhex.c (getvalue): Check for the source pointer exceeding the end pointer before the first byte is read.
Hi Owl, Thanks for reporting this bug. I have checked in a small patch to fix the problem, which was a simple case of not checking for a buffer overrun early enough. Cheers Nick