https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90924
Bug ID: 90924 Summary: lto-plugin/lto-plugin.c heap memory corruption due to insufficient sanitization. Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: plugins Assignee: unassigned at gcc dot gnu.org Reporter: rkx1209dev at gmail dot com Target Milestone: --- Created attachment 46501 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46501&action=edit Proof of Concept ELF binary for nm command On several major linux distributions like ubuntu, debian... binutils uses ELF parser from gold linker plugin, /usr/lib/gcc/x86_64-linux-gnu/9/liblto_plugin.so instead of libbfd. I found a memory corruption bug (Heap OOB read) of gold ELF parser linked from latest nm command(2.30). If input binary file has a zero value string section offset (i.e e_shstrndx == 0.), gold ELF parser try to find string section by simple_object_find_sections() without enough sanitization. https://github.com/gcc-mirror/gcc/blob/6c552ff765c1b02d3ec9094f92c1ce58f8cda14b/lto-plugin/lto-plugin.c#L1059 As a result if e_shstrndx is equal to 0, "(eor->shstrndx - 1)" at this line cause integer overflow (a result becomes negative value (unsigned int)-1 ) https://github.com/gcc-mirror/gcc/blob/6c552ff765c1b02d3ec9094f92c1ce58f8cda14b/libiberty/simple-object-elf.c#L600 and try to do out of bound access against heap memory, cause memory corruption. On Ubuntu 18.10 with GCC 9.1.0. PoC file is attached to this email. Execute PoC: nm ./memcorrupt_nm-2.30_gcc-9.1.0_gold Segmentation fault (core dumped) CrashDump: nm --plugin ./gcc-9.1.0/build/lto-plugin/.libs/liblto_plugin.so.0.0.0 ./memcorrupt_nm-2.30_gcc-9.1.0_gold Core was generated by `nm --plugin ./gcc-9.1.0/build/lto-plugin/.libs/liblto_plugin.so.0.0.0 ./researc'. Program terminated with signal SIGSEGV, Segmentation fault. #0 simple_object_fetch_little_64 (buf=0x5678b4bc3640 <error: Cannot access memory at address 0x5678b4bc3640>) at ../../libiberty/simple-object-common.h:262 262 return (((ulong_type) buf[7] << 56) (gdb) bt #0 simple_object_fetch_little_64 (buf=0x5678b4bc3640 <error: Cannot access memory at address 0x5678b4bc3640>) at ../../libiberty/simple-object-common.h:262 #1 0x00007feb2c5b7268 in simple_object_elf_find_sections (sobj=0x5638b4bc3630, pfn=0x7feb2c5b0930 <process_symtab>, data=0x7ffd5884ca00, err=0x7ffd5884c9f4) at ../../libiberty/simple-object-elf.c:601 #2 0x00007feb2c5b0dd5 in claim_file_handler (file=0x7ffd5884cac0, claimed=0x7ffd5884cabc) at ../../lto-plugin/lto-plugin.c:1025 #3 0x00007feb2c49796b in ?? () from /usr/lib/x86_64-linux-gnu/libbfd-2.31.1-multiarch.so #4 0x00007feb2c497bef in ?? () from /usr/lib/x86_64-linux-gnu/libbfd-2.31.1-multiarch.so #5 0x00007feb2c30880a in bfd_check_format_matches () from /usr/lib/x86_64-linux-gnu/libbfd-2.31.1-multiarch.so #6 0x00005638b4012cb0 in ?? () #7 0x00005638b40109e6 in ?? () #8 0x00007feb2c07f09b in __libc_start_main (main=0x5638b4010590, argc=4, argv=0x7ffd5884ceb8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffd5884cea8) at ../csu/libc-start.c:308 #9 0x00005638b4010a5a in ?? () ``` Thanks Ren