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

Reply via email to