bug-binutils
[Top][All Lists]
Advanced

[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

https://sourceware.org/bugzilla/show_bug.cgi?id=23850

            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)
relocations.
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
https://reviews.llvm.org/D52830
  [ 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 
./a.stripped

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
time.

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

//
https://sourceware.org/git/?p=glibc.git;a=blob;hb=fc783076ec496a55c029be14617ea16a24589f55;f=csu/libc-start.c#l78
glibc/csu/libc-start.c

  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
  }
  #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.

https://sourceware.org/git/?p=binutils-gdb.git;a=blob;hb=cdcda965ea4c70c80b9f8c294597e991417ff9d5;f=binutils/readelf.c#l6307
        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 !=
SHT_SYMTAB
                  && filedata->section_headers[section->sh_link].sh_type !=
SHT_DYNSYM))
            warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
                  i, section->sh_link);
          break;


https://docs.oracle.com/cd/E19683-01/816-1386/6m7qcoblj/index.html#chapter6-47976
says
  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]