Bug 1235068

Summary: prelink-0.5.0-1.fc20.x86_64 corrupts ld.so built with binutils master branch
Product: [Fedora] Fedora Reporter: H.J. Lu <hongjiu.lu>
Component: prelinkAssignee: Jakub Jelinek <jakub>
Status: CLOSED EOL QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 22CC: jakub, mjw
Target Milestone: ---   
Target Release: ---   
Hardware: x86_64   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-07-19 15:00:41 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description H.J. Lu 2015-06-23 22:45:55 UTC
prelink-0.5.0-1.fc20.x86_64 corrupts ld.so built with binutils master branch,
which has several new features, including

[hjl@gnu-ivb-1 ~]$ readelf -SW /lib64/ld-linux-x86-64.so.2 
There are 26 section headers, starting at offset 0x27338:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .note.gnu.build-id NOTE            00000000000001c8 0001c8 000024 00   A  0   0  4
  [ 2] .hash             HASH            00000000000001f0 0001f0 0000c0 04   A  4   0  8
  [ 3] .gnu.hash         GNU_HASH        00000000000002b0 0002b0 0000e0 00   A  4   0  8
  [ 4] .dynsym           DYNSYM          0000000000000390 000390 0002b8 18   A  5   2  8
  [ 5] .dynstr           STRTAB          0000000000000648 000648 0001a4 00   A  0   0  1
  [ 6] .gnu.version      VERSYM          00000000000007ec 0007ec 00003a 02   A  4   0  2
  [ 7] .gnu.version_d    VERDEF          0000000000000828 000828 0000a4 00   A  5   5  8
  [ 8] .rela.dyn         RELA            00000000000008d0 0008d0 000180 18   A  4   0  8
  [ 9] .plt.got          PROGBITS        0000000000000a50 000a50 000028 00  AX  0   0  8
  [10] .text             PROGBITS        0000000000000a80 000a80 01ac70 00  AX  0   0 16
  [11] .rodata           PROGBITS        000000000001b700 01b700 002c80 00   A  0   0 64
  [12] .stapsdt.base     PROGBITS        000000000001e380 01e380 000001 00   A  0   0  1
  [13] .eh_frame_hdr     PROGBITS        000000000001e384 01e384 000614 00   A  0   0  4
  [14] .eh_frame         PROGBITS        000000000001e998 01e998 002348 00   A  0   0  8
  [15] .data.rel.ro      PROGBITS        0000000000221bc0 021bc0 00026c 00  WA  0   0 64
  [16] .dynamic          DYNAMIC         0000000000221e30 021e30 000150 10  WA  5   0  8
  [17] .got              PROGBITS        0000000000221f80 021f80 000048 08  WA  0   0  8
  [18] .data             PROGBITS        0000000000222000 022000 000f84 00  WA  0   0 64
  [19] .bss              NOBITS          0000000000222fa0 022f84 0001a8 00  WA  0   0 32
  [20] .comment          PROGBITS        0000000000000000 022f84 00002c 01  MS  0   0  1
  [21] .note.stapsdt     NOTE            0000000000000000 022fb0 000404 00      0   0  4
  [22] .symtab           SYMTAB          0000000000000000 0233b8 002a60 18     23 425  8
  [23] .strtab           STRTAB          0000000000000000 025e18 001413 00      0   0  1
  [24] .gnu_debuglink    PROGBITS        0000000000000000 02722c 000018 00      0   0  4
  [25] .shstrtab         STRTAB          0000000000000000 027244 0000f2 00      0   0  1

There is no .plt section, only .plt.got section.  There are no PLT
relocations:

[hjl@gnu-ivb-1 ~]$ readelf -r  /lib64/ld-linux-x86-64.so.2 

Relocation section '.rela.dyn' at offset 0x8d0 contains 16 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000221d48  000000000008 R_X86_64_RELATIVE                    10d50
000000221d50  000000000008 R_X86_64_RELATIVE                    fcd0
000000221d58  000000000008 R_X86_64_RELATIVE                    fa90
000000221d60  000000000008 R_X86_64_RELATIVE                    11f60
000000221d68  000000000008 R_X86_64_RELATIVE                    a5e0
000000221d70  000000000008 R_X86_64_RELATIVE                    13240
000000221d78  000000000008 R_X86_64_RELATIVE                    13d90
000000221d80  000000000008 R_X86_64_RELATIVE                    161b0
000000221d88  000000000008 R_X86_64_RELATIVE                    12e40
000000221d90  000000000008 R_X86_64_RELATIVE                    17bb0
000000221f98  000c00000006 R_X86_64_GLOB_DAT 0000000000017e40 __libc_memalign@@GLIBC_2.2.5 + 0
000000221fa0  001800000006 R_X86_64_GLOB_DAT 0000000000017f40 malloc@@GLIBC_2.2.5 + 0
000000221fa8  000f00000006 R_X86_64_GLOB_DAT 0000000000017f50 calloc@@GLIBC_2.2.5 + 0
000000221fb0  000700000006 R_X86_64_GLOB_DAT 0000000000017fc0 realloc@@GLIBC_2.2.5 + 0
000000221fb8  000a00000006 R_X86_64_GLOB_DAT 0000000000223120 _r_debug@@GLIBC_2.2.5 + 0
000000221fc0  000600000006 R_X86_64_GLOB_DAT 0000000000017f90 free@@GLIBC_2.2.5 + 0
[hjl@gnu-ivb-1 ~]$

Comment 1 H.J. Lu 2015-06-24 22:55:32 UTC
This was caused by binutils commit:

commit a3747075ae478f27bf3e0643021a85fb6cdad0e3
Author: H.J. Lu <hjl.tools>
Date:   Tue May 12 13:11:48 2015 -0700

    Allocate the first .plt entry space only if needed
    
    Commit dd7e64d45b317128f5fe813a8da0b13b4ad046ae may optimize out
    i386/x86-64 JUMP_SLOT relocation.  If there is no JUMP_SLOT relocation
    left, we don't need to the first .plt entry.  This patch allocates
    space for the first .plt entry only if we also reserve space for a PLT
    slot for JUMP_SLOT relocation.
    
    bfd/
    
      * elf32-i386.c (elf_i386_allocate_dynrelocs): Allocate space
      for the first .plt entry only if needed.
      * elf64-x86-64.c (elf_x86_64_allocate_dynrelocs): Likewise.

prelink didn't check if .plt section and DT_PLTGOT existed and
performed prelink.  Without .plt section and DT_PLTGOT, ld.so
can't undo prelinking and nothing works.  Linker is fixed by

commit 7c1e8d3ed5e48b3339d60450fdb5b29ae54edebe
Author: H.J. Lu <hjl.tools>
Date:   Wed Jun 24 13:37:05 2015 -0700

    Keep .plt section and DT_PLTGOT for prelink
    
    Since the .plt section and DT_PLTGOT are used by prelink to undo
    prelinking for dynamic relocations, we must keep them even if there is
    no PLT relocation.  This patch reverted commit a3747075a.
    
    bfd/
    
      * elf32-i386.c (elf_i386_allocate_dynrelocs): Always allocate
      space for the first .plt entry.
      (elf_i386_size_dynamic_sections): Always add DT_PLTGOT for .plt
      section.  Add DT_PLTRELSZ, DT_PLTREL and DT_JMPREL only if
      there are PLT relocations.
      * elf64-x86-64.c (elf_x86_64_allocate_dynrelocs): Always
      allocate space for the first .plt entry.
      (elf_x86_64_size_dynamic_sections): Always add DT_PLTGOT for
      .plt section.  Add DT_PLTRELSZ, DT_PLTREL and DT_JMPREL only if
      there are PLT relocations.

prelink should check for .plt section and DT_PLTGOT before creating
broken ld.so.

Comment 2 Fedora End Of Life 2016-07-19 15:00:41 UTC
Fedora 22 changed to end-of-life (EOL) status on 2016-07-19. Fedora 22 is
no longer maintained, which means that it will not receive any further
security or bug fix updates. As a result we are closing this bug.

If you can reproduce this bug against a currently maintained version of
Fedora please feel free to reopen this bug against that version. If you
are unable to reopen this bug, please file a new report against the
current release. If you experience problems, please add a comment to this
bug.

Thank you for reporting this bug and we are sorry it could not be fixed.