[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug binutils/23850] New: GNU strip should not discard/move .rela.plt in

From: maskray at google dot com
Subject: [Bug binutils/23850] New: GNU strip should not discard/move .rela.plt in executable linking glibc statically
Date: Thu, 01 Nov 2018 15:13:27 +0000


            Bug ID: 23850
           Summary: GNU strip should not discard/move .rela.plt in
                    executable linking glibc statically
           Product: binutils
           Version: 2.32 (HEAD)
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: maskray at google dot com
  Target Milestone: ---

This is similar to Bug 10337 but is a different incarnation.

When linking glibc statically, .rel?.plt contains R_*_IRELATIVE (e.g. strcpy)
If such .rela.plt section has sh_link pointing to .symtab,
GNU strip will produce a corrupted executable that crashes at run time.

% clang -fuse-ld=lld -static -xc =(printf 'int main(){}') -o a
# or gcc on a Debian derivative with the -fuse-ld=lld patch

% readelf -WS a
  [Nr] Name              Type            Address          Off    Size   ES Flg
Lk Inf Al
  # .rela.plt has sh_link pointing to .symtab after
  [ 1] .rela.plt         RELA            0000000000200238 000238 000108 18   A
32  20  8
  [32] .symtab           SYMTAB          0000000000000000 0b62a8 00a9e0 18    
34 694  8

% strip a -o a.stripped; ./a.stripped
unexpected reloc type in static binary[1]    164865 segmentation fault 

The crash is because .rela.plt is discarded (in a more complicated case there
may be a new .rela.got.plt but I haven't delved into the details)
and its place [__rela_iplt_start, __rela_iplt_end) is filled by zeroes.

    __rela_iplt_start __rela_iplt_end are static relocations resolved at link

When running the stripped executable, apply_irel in libc initialization will
error `unexpected reloc type in static binary` and a crash ensues.


  static void
  apply_irel (void)
  # ifdef IREL
    /* We use weak references for these so that we'll still work with a linker
       that doesn't define them.  Such a linker doesn't support IFUNC at all
       and so uses won't work, but a statically-linked program that doesn't
       use any IFUNC symbols won't have a problem.  */
    extern const IREL_T IPLT_START[] __attribute__ ((weak));
    extern const IREL_T IPLT_END[] __attribute__ ((weak));
    //////// IPLT_START (__rela_iplt_start) points to a zero-filled region
    for (const IREL_T *ipltent = IPLT_START; ipltent < IPLT_END; ++ipltent)
      IREL (ipltent);
  # endif

Note ld.bfd and gold synthesize .rela.plt with sh_link=0 and do not have the
issue, but changing sh_link to .symtab will also break. Moreever, GNU readelf
has a warning:

% readelf -WS a
readelf: Warning: [ 3]: Link field (0) should index a symtab section.

        case SHT_REL:
        case SHT_RELA:
          if (section->sh_link < 1
              || section->sh_link >= filedata->file_header.e_shnum
              || (filedata->section_headers[section->sh_link].sh_type !=
                  && filedata->section_headers[section->sh_link].sh_type !=
            warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
                  i, section->sh_link);

  SHT_REL SH_RELA sections' sh_link point to "The section header index of the
associated symbol table."

It seems to me that in absence of .dymsym, sh_link=.symtab makes more sense
than 0.

You are receiving this mail because:
You are on the CC list for the bug.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]