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. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils