Summary: | ld should warn or error out about creating copy relocs & direct external references for protected symbols | ||
---|---|---|---|
Product: | binutils | Reporter: | Thiago Macieira <thiago> |
Component: | ld | Assignee: | H.J. Lu <hjl.tools> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | hjl.tools, pinskia |
Priority: | P2 | ||
Version: | 2.38 | ||
Target Milestone: | 2.39 | ||
See Also: |
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37611 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19520 |
||
Host: | Target: | ||
Build: | Last reconfirmed: | 2022-02-10 00:00:00 | |
Attachments: |
A patch
The v2 patch |
Description
Thiago Macieira
2022-02-09 19:59:02 UTC
Created attachment 13964 [details]
A patch
Try this.
(In reply to H.J. Lu from comment #1) > Created attachment 13964 [details] > A patch > > Try this. Confirmed for copy relocations: $ cat main.cpp extern __attribute__((visibility("default"))) long internal_i; extern __attribute__((visibility("default"))) long internal_f(); int main() { internal_i = (long) &internal_f; return (long) &internal_f; } $ gcc main.cpp libb.so /home/tjmaciei/dev/gcc/lib/gcc/x86_64-pc-linux-gnu/12.0.1/../../../../x86_64-pc-linux-gnu/bin/ld: /tmp/ccwnIS4o.o: copy relocation against non-copyable protected symbol `internal_i' in libb.so collect2: error: ld returned 1 exit status But not for PLT entries: $ cat main2.cpp extern __attribute__((visibility("default"))) long internal_f(); int main() { return (long) &internal_f; } $ gcc main2.cpp libb.so [no error] $ objdump --no-show -Cdr a.out| sed -n '/<main>:/,/^$/p' 0000000000401126 <main>: 401126: push %rbp 401127: mov %rsp,%rbp 40112a: mov $0x401030,%eax 40112f: pop %rbp 401130: ret glibc 2.35 does not complain about this binary by default: $ LD_LIBRARY_PATH=. ./a.out; printf %x\\n $? 30 Only if the PLT is processed: $ LD_BIND_NOW=1 LD_LIBRARY_PATH=. ./a.out ./a.out: _Z10internal_fv: ./libb.so: non-canonical reference to canonical protected function That is, this patch brings BFD ld on par with Gold. The remaining issue for Gold is #28876. Created attachment 13971 [details]
The v2 patch
I got
/usr/gcc-12.0.1-x32/bin/gcc -B./ -o x main.o libfoo.so -Wl,-R,.
./ld: main.o: non-canonical reference to canonical protected function `internal_f' in libfoo.so
./ld: failed to set dynamic section sizes: bad value
collect2: error: ld returned 1 exit status
(In reply to H.J. Lu from comment #4) > Created attachment 13971 [details] > The v2 patch > > I got > > /usr/gcc-12.0.1-x32/bin/gcc -B./ -o x main.o libfoo.so -Wl,-R,. > ./ld: main.o: non-canonical reference to canonical protected function > `internal_f' in libfoo.so > ./ld: failed to set dynamic section sizes: bad value > collect2: error: ld returned 1 exit status Confirmed: $ gcc main.cpp libb.so /home/tjmaciei/dev/gcc/lib/gcc/x86_64-pc-linux-gnu/12.0.1/../../../../x86_64-pc-linux-gnu/bin/ld: /tmp/ccTtYFXS.o: non-canonical reference to canonical protected function `_Z10internal_fv' in libb.so collect2: error: ld returned 1 exit status Uploading my Qt patch to make use of this. The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ebb191adac4ab45498dec0bfaac62f0a33537ba4 commit ebb191adac4ab45498dec0bfaac62f0a33537ba4 Author: H.J. Lu <hjl.tools@gmail.com> Date: Wed Feb 9 15:51:22 2022 -0800 x86: Disallow invalid relocation against protected symbol I am checking this into master and will backport it to 2.38 branch. H.J ---- On x86, GCC 12 supports -mno-direct-extern-access to enable canonical reference to protected function and disable copy relocation. With -mno-direct-extern-access, the canonical protected function symbols must be accessed via canonical reference and the protected data symbols in shared libraries are non-copyable. Under glibc 2.35, non-canonical reference to the canonical protected function will get the run-time error: ./y: internal_f: ./libfoo.so: non-canonical reference to canonical protected function and copy relocations against the non-copyable protected symbols will get the run-time error: ./x: internal_i: ./libfoo.so: copy relocation against non-copyable protected symbol Update x86 linker to disallow non-canonical reference to the canonical protected function: ld: plt.o: non-canonical reference to canonical protected function `internal_f' in libfoo.so ld: failed to set dynamic section sizes: bad value and copy relocation against the non-copyable protected symbol: ld: main.o: copy relocation against non-copyable protected symbol `internal_i' in libfoo.so at link-time. bfd/ PR ld/28875 * elf-properties.c (_bfd_elf_parse_gnu_properties): Don't skip shared libraries for GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. * elf32-i386.c (elf_i386_scan_relocs): Disallow non-canonical reference to canonical protected function. * elf64-x86-64.c (elf_x86_64_scan_relocs): Likewise. * elfxx-x86.c (elf_x86_allocate_dynrelocs): Don't allow copy relocation against non-copyable protected symbol. ld/ PR ld/28875 * testsuite/ld-i386/i386.exp: Check non-canonical reference to canonical protected function and check copy relocation against non-copyable protected symbol. * testsuite/ld-i386/pr21997-1.err: New file. * testsuite/ld-i386/pr28875.err: Likewise. * testsuite/ld-i386/pr28875a.c: Likewise. * testsuite/ld-i386/pr28875b.c: Likewise. * testsuite/ld-x86-64/pr21997-1a.err: Updated. * testsuite/ld-x86-64/pr21997-1b.err: Likewise. * testsuite/ld-x86-64/pr28875-data.err: New file. * testsuite/ld-x86-64/pr28875-func.err: Likewise. * testsuite/ld-x86-64/x86-64.exp: Check non-canonical reference to canonical protected function and check copy relocation against non-copyable protected symbol. The binutils-2_38-branch branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=caa6172de4b5100c9b45fd03eae714167a6085c1 commit caa6172de4b5100c9b45fd03eae714167a6085c1 Author: H.J. Lu <hjl.tools@gmail.com> Date: Wed Feb 9 15:51:22 2022 -0800 x86: Disallow invalid relocation against protected symbol I am checking this into master and will backport it to 2.38 branch. H.J ---- On x86, GCC 12 supports -mno-direct-extern-access to enable canonical reference to protected function and disable copy relocation. With -mno-direct-extern-access, the canonical protected function symbols must be accessed via canonical reference and the protected data symbols in shared libraries are non-copyable. Under glibc 2.35, non-canonical reference to the canonical protected function will get the run-time error: ./y: internal_f: ./libfoo.so: non-canonical reference to canonical protected function and copy relocations against the non-copyable protected symbols will get the run-time error: ./x: internal_i: ./libfoo.so: copy relocation against non-copyable protected symbol Update x86 linker to disallow non-canonical reference to the canonical protected function: ld: plt.o: non-canonical reference to canonical protected function `internal_f' in libfoo.so ld: failed to set dynamic section sizes: bad value and copy relocation against the non-copyable protected symbol: ld: main.o: copy relocation against non-copyable protected symbol `internal_i' in libfoo.so at link-time. bfd/ PR ld/28875 * elf-properties.c (_bfd_elf_parse_gnu_properties): Don't skip shared libraries for GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. * elf32-i386.c (elf_i386_scan_relocs): Disallow non-canonical reference to canonical protected function. * elf64-x86-64.c (elf_x86_64_scan_relocs): Likewise. * elfxx-x86.c (elf_x86_allocate_dynrelocs): Don't allow copy relocation against non-copyable protected symbol. ld/ PR ld/28875 * testsuite/ld-i386/i386.exp: Check non-canonical reference to canonical protected function and check copy relocation against non-copyable protected symbol. * testsuite/ld-i386/pr21997-1.err: New file. * testsuite/ld-i386/pr28875.err: Likewise. * testsuite/ld-i386/pr28875a.c: Likewise. * testsuite/ld-i386/pr28875b.c: Likewise. * testsuite/ld-x86-64/pr21997-1a.err: Updated. * testsuite/ld-x86-64/pr21997-1b.err: Likewise. * testsuite/ld-x86-64/pr28875-data.err: New file. * testsuite/ld-x86-64/pr28875-func.err: Likewise. * testsuite/ld-x86-64/x86-64.exp: Check non-canonical reference to canonical protected function and check copy relocation against non-copyable protected symbol. (cherry picked from commit ebb191adac4ab45498dec0bfaac62f0a33537ba4) Fixed for 2.39 and 2.38 branch. |