Bug 20428 - ld powerpc64le NULL deref in ppc_get_stub_entry when linking code in not-executable sections
Summary: ld powerpc64le NULL deref in ppc_get_stub_entry when linking code in not-exec...
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.28
: P2 normal
Target Milestone: ---
Assignee: Alan Modra
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-08-02 05:45 UTC by npiggin
Modified: 2016-08-03 06:05 UTC (History)
0 users

See Also:
Host: powerpc64le-unknown-linux-gnu
Target: powerpc64le-unknown-linux-gnu
Build:
Last reconfirmed: 2016-08-02 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description npiggin 2016-08-02 05:45:29 UTC
This bug happens with git master commit 80b476c2bf85be6676cc6b55dab232730e124147, also with the 2.26.51 build.

Host and target are powerpc64le

If we have foo.S:

.section ".rodata","a"
.global foo
foo:
        bne     main

And link it with main function in another section, then the linker crashes. gdb (from the same source build) reports:

Starting program: /home/npiggin/src/binutils/binutils-gdb/ld/ld-new -o test main.o test.o
/home/npiggin/src/binutils/binutils-gdb/ld/ld-new: warning: cannot find entry symbol _start; defaulting to 00000000100000b0

Program received signal SIGSEGV, Segmentation fault.
0x00000000100822a8 in ppc_get_stub_entry (input_section=0x102734c0, 
    htab=0x10249c30, rel=0x3fffffffe9a0, h=0x1024a658, sym_sec=0x10273390)
    at elf64-ppc.c:4510
4510	      && h->u.stub_cache->h == h

(gdb) list
4505	     more than one stub used to reach say, printf, and we need to
4506	     distinguish between them.  */
4507	  group = htab->sec_info[input_section->id].u.group;
4508	
4509	  if (h != NULL && h->u.stub_cache != NULL
4510	      && h->u.stub_cache->h == h
4511	      && h->u.stub_cache->group == group)
4512	    {
4513	      stub_entry = h->u.stub_cache;
4514	    }

(gdb) bt
#0  0x00000000100822a8 in ppc_get_stub_entry (input_section=0x102734c0, 
    htab=0x10249c30, rel=0x3fffffffe9a0, h=0x1024a658, sym_sec=0x10273390)
    at elf64-ppc.c:4510
#1  ppc64_elf_relocate_section (output_bfd=0x102478a0, 
    info=0x1022a150 <link_info>, input_bfd=0x10271e60, 
    input_section=0x102734c0, contents=0x102751f0 "", relocs=0x10275cd0, 
    local_syms=0x1028d0a0, local_sections=0x1028d3e0) at elf64-ppc.c:14013
#2  0x00000000100b8d3c in elf_link_input_bfd (flinfo=0x3fffffffed68, 
    input_bfd=0x10271e60) at elflink.c:10367
#3  0x00000000100ba8fc in bfd_elf_final_link (abfd=0x102478a0, 
    info=0x1022a150 <link_info>) at elflink.c:11677
#4  0x0000000010022d40 in ldwrite () at ldwrite.c:577
#5  0x0000000010004490 in main (argc=5, argv=0x3ffffffff518) at ./ldmain.c:431


However looking at the disassembly, gdb seems to be getting this wrong. h->u.stub_cache is NULL, but we seem to actually be crashing on line 4519 because group is also NULL.

If branches remain within local section, the result links okay, so it's crashing trying to generate linker stub in non-executable section. The stub turns out to be unneeded after linking is complete, so it would be nice if we could allow this case.
Comment 1 npiggin 2016-08-02 05:53:56 UTC
For better or worse, Linux kernel wants to do this in order to run a test case for non-executable mapping of data. Other architectures seem to work, and gold with powerpc64le works with my simple test case.
Comment 2 Alan Modra 2016-08-02 14:01:56 UTC
Gah, code in non-exec sections?
Comment 3 Sourceware Commits 2016-08-02 14:22:19 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=89d77b8a520602832516ce6628ea930b4f0ccff4

commit 89d77b8a520602832516ce6628ea930b4f0ccff4
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Aug 2 23:28:47 2016 +0930

    PowerPC64 ld segfault with code in non-executable sections
    
    	PR ld/20428
    	* elf64-ppc.c (ppc_get_stub_entry): Don't segfault on NULL group.
Comment 4 Sourceware Commits 2016-08-03 05:47:18 UTC
The binutils-2_27-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=24ef2be9b6ca8276a62b3f60f845f4c8bb6194dd

commit 24ef2be9b6ca8276a62b3f60f845f4c8bb6194dd
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Aug 2 23:28:47 2016 +0930

    PowerPC64 ld segfault with code in non-executable sections
    
    	PR ld/20428
    	* elf64-ppc.c (ppc_get_stub_entry): Don't segfault on NULL group.
Comment 5 Sourceware Commits 2016-08-03 05:48:21 UTC
The binutils-2_26-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d45d94d9484e5f22e1e414a17f8d4317f4f1ee37

commit d45d94d9484e5f22e1e414a17f8d4317f4f1ee37
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Aug 2 23:28:47 2016 +0930

    PowerPC64 ld segfault with code in non-executable sections
    
    	PR ld/20428
    	* elf64-ppc.c (ppc_get_stub_entry): Don't segfault on NULL group.
Comment 6 Alan Modra 2016-08-03 06:05:16 UTC
Fixed