Bug 23772 - A NULL-Pointer dereference problems in ldlang.c in program ld (member access within null pointer of type 'union lang_statement_union')
Summary: A NULL-Pointer dereference problems in ldlang.c in program ld (member access ...
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.31
: P2 normal
Target Milestone: 2.34
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-10-13 09:06 UTC by wcventure
Modified: 2019-11-21 23:02 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
POC (37 bytes, text/x-matlab)
2018-10-13 09:06 UTC, wcventure
Details

Note You need to log in before you can comment on or make changes to this bug.
Description wcventure 2018-10-13 09:06:33 UTC
Created attachment 11324 [details]
POC

Hi, there.

A NULL-Pointer dereference problems in program ld of the latest binutils code base. A crafted input can cause the member access within null pointer of type 'union lang_statement_union' in ldlang.c.

I have confirmed it with address sanitizer too. Please use the "./ld -E $POC" to reproduce the bug.


The ASAN dumps the stack trace as follows:
./ld: unknown architecture of input file `POC_ld_NULLp1' is incompatible with i386:x86-64 output
ldlang.c:916:7: runtime error: member access within null pointer of type 'union lang_statement_union'
SUMMARY: AddressSanitizer: undefined-behavior ldlang.c:916:7 in
ldlang.c:931:7: runtime error: member access within null pointer of type 'union lang_statement_union'
SUMMARY: AddressSanitizer: undefined-behavior ldlang.c:931:7 in
ldlang.c:6726:3: runtime error: member access within null pointer of type 'union lang_statement_union'
SUMMARY: AddressSanitizer: undefined-behavior ldlang.c:6726:3 in
eelf_x86_64.c:1646:5: runtime error: member access within null pointer of type 'union lang_statement_union'
SUMMARY: AddressSanitizer: undefined-behavior eelf_x86_64.c:1646:5 in
./ld: warning: cannot find entry symbol _start; not setting start address
==11972==WARNING: AddressSanitizer failed to allocate 0x11131111110 bytes
==11972==AddressSanitizer's allocator is terminating the process instead of returning 0
==11972==If you don't like this behavior set allocator_may_return_null=1
==11972==AddressSanitizer CHECK failed: /build/llvm-toolchain-3.8-_PD09B/llvm-toolchain-3.8-3.8/projects/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc:147 "((0)) != (0)" (0x0, 0x0)
    #0 0x4c2ccd in __asan::AsanCheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/media/hjwang/01D3344861A8D2E0/wcventure/Project/binutils_ASAN_O1/build/bin/ld+0x4c2ccd)
    #1 0x4c98f3 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/media/hjwang/01D3344861A8D2E0/wcventure/Project/binutils_ASAN_O1/build/bin/ld+0x4c98f3)
    #2 0x4c7476 in __sanitizer::ReportAllocatorCannotReturnNull() (/media/hjwang/01D3344861A8D2E0/wcventure/Project/binutils_ASAN_O1/build/bin/ld+0x4c7476)
    #3 0x41f28c in __asan::asan_malloc(unsigned long, __sanitizer::BufferedStackTrace*) (/media/hjwang/01D3344861A8D2E0/wcventure/Project/binutils_ASAN_O1/build/bin/ld+0x41f28c)
    #4 0x4b96a1 in malloc (/media/hjwang/01D3344861A8D2E0/wcventure/Project/binutils_ASAN_O1/build/bin/ld+0x4b96a1)
    #5 0xc7fb87 in bfd_malloc /media/hjwang/01D3344861A8D2E0/wcventure/Project/binutils_ASAN_O1/bfd/libbfd.c:271:9
    #6 0x16bd13f in bfd_elf_final_link /media/hjwang/01D3344861A8D2E0/wcventure/Project/binutils_ASAN_O1/bfd/elflink.c:12035:38
    #7 0x7e87dc in ldwrite /media/hjwang/01D3344861A8D2E0/wcventure/Project/binutils_ASAN_O1/ld/ldwrite.c:581:8
    #8 0x7bac80 in main /media/hjwang/01D3344861A8D2E0/wcventure/Project/binutils_ASAN_O1/ld/./ldmain.c:454:3
    #9 0x7efcf5e8282f in __libc_start_main /build/glibc-Cl5G7W/glibc-2.23/csu/../csu/libc-start.c:291
    #10 0x4195b8 in _start (/media/hjwang/01D3344861A8D2E0/wcventure/Project/binutils_ASAN_O1/build/bin/ld+0x4195b8)

Aborted

(This bug was found by NTU-Cyber Security Lab. If you have any questions, please let me know.)
Comment 1 Alan Modra 2018-10-15 00:47:02 UTC
I could not reproduce the "member access within null pointer" errors.  How did you configure and compile binutils?  It seems likely to me that these error are due to compiler or asan bugs.

As with the other bug, the memory allocation failure isn't interesting.
Comment 2 wcventure 2018-10-15 12:16:05 UTC
My configure and compile option is:

> CC=clang LDFLAGS="-ldl" CFLAGS="-DFORTIFY_SOURCE=2 -fstack-protector-all -fsanitize=undefined,address -fno-omit-frame-pointer -g -O0 -Wno-error" ./configure --disable-shared --disable-gdb --disable-libdecnumber --disable-sim --prefix=$PWD/build/
> make
> make install

I use POC as input. The program displays the following error:

> $ ./ld -E POC_ld_NULLp1
> ./ld: unknown architecture of input file `POC_ld_NULLp1' is incompatible with i386:x86-64 output
> ldlang.c:916:7: runtime error: member access within null pointer of type 'union lang_statement_union'
> SUMMARY: AddressSanitizer: undefined-behavior ldlang.c:916:7 in
> ldlang.c:931:7: runtime error: member access within null pointer of type 'union lang_statement_union'
> SUMMARY: AddressSanitizer: undefined-behavior ldlang.c:931:7 in
> ldlang.c:6726:3: runtime error: member access within null pointer of type 'union lang_statement_union'
> SUMMARY: AddressSanitizer: undefined-behavior ldlang.c:6726:3 in
> eelf_x86_64.c:1646:5: runtime error: member access within null pointer of type 'union lang_statement_union'
> SUMMARY: AddressSanitizer: undefined-behavior eelf_x86_64.c:1646:5 in
> ./ld: warning: cannot find entry symbol _start; not setting start address

I have debugged this program again. I will show you de debug process. I set a break point at ldlang.c:916. After twice reach the break point. I typed "print f" and the gdb show that the vlaue of variable f is "(lang_input_statement_type *) 0x0".

> $ gdb --args ./ld -E POC
> GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
> Copyright (C) 2016 Free Software Foundation, Inc.
> This GDB was configured as "x86_64-linux-gnu".
> Reading symbols from ./ld...done.
> (gdb) start
> Temporary breakpoint 1 at 0x5f9eb9: file ./ldmain.c, line 192.
> Starting program: /media/hjwang/01D3344861A8D2E0/wcventure/Project/binutils_ASAN_O0/build/bin/ld -E POC_ld_NULLp1
> [Thread debugging using libthread_db enabled]
> Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
> 
> Temporary breakpoint 1, main (argc=<error reading variable: Cannot access memory at address 0x0>,
>     argv=<error reading variable: Cannot access memory at address 0x1>) at ./ldmain.c:192
> 192     {
> (gdb) b ldlang.c:916
> Breakpoint 2 at 0x5d7d6b: file ldlang.c, line 916.
> (gdb) continue
> Continuing.
> ./build/bin/ld: unknown architecture of input file `POC_ld_NULLp1' is incompatible with i386:x86-64 output
> 
> Breakpoint 2, walk_wild (s=0x619000005d40, callback=0x5d8580 <gc_section_callback>, data=0x0) at ldlang.c:916
> 916           LANG_FOR_EACH_INPUT_STATEMENT (f)
> (gdb) p f
> $1 = (lang_input_statement_type *) 0x621000012f20
> (gdb) c
> Continuing.
> ldlang.c:916:7: runtime error: member access within null pointer of type 'union lang_statement_union'
> SUMMARY: AddressSanitizer: undefined-behavior ldlang.c:916:7 in
> 
> Breakpoint 2, walk_wild (s=0x619000001e90, callback=0x5d8580 <gc_section_callback>, data=0x0) at ldlang.c:916
> 916           LANG_FOR_EACH_INPUT_STATEMENT (f)
> (gdb) p f
> $2 = (lang_input_statement_type *) 0x0
> (gdb) c
> Continuing.
> 
> Breakpoint 2, walk_wild (s=0x619000001f10, callback=0x5d8580 <gc_section_callback>, data=0x0) at ldlang.c:916
> 916           LANG_FOR_EACH_INPUT_STATEMENT (f)
> (gdb) p f
> $3 = (lang_input_statement_type *) 0x0

The runtime error shows that there exists a member access within Null pointer of type 'union lang_statement_union'.

If you have any questions, please let me know.
Comment 3 Alan Modra 2018-10-15 14:07:14 UTC
I think thas asan is complaining about
   statement = &statement->next->input_statement
from ldlang.h:591 when statement->next is NULL.

I also think that complaint is bogus.
Comment 4 Alan Modra 2019-11-21 23:02:12 UTC
git commit 36983a93bb avoided the construct complained about here by asan.