Related: #15228, #17711, #27973. For a library that has protected symbols: $ cat libb2.cpp __attribute__((visibility("protected"))) long internal_i = 0; __attribute__((visibility("protected"))) long internal_f() { return 2; } $ gcc -shared -fPIC -o libb.so libb2.cpp $ eu-readelf --dyn-syms libb.so| grep internal 5: 0000000000004028 8 OBJECT GLOBAL PROTECTED 22 internal_i 6: 00000000000010f9 11 FUNC GLOBAL PROTECTED 11 _Z10internal_fv The linker should produce a warning when creating copy relocations or position-dependent moves: $ cat main.cpp extern __attribute__((visibility("default"))) long internal_i; extern __attribute__((visibility("default"))) long internal_f(); int main() { internal_i = (long) &internal_f; } $ gcc main.cpp libb.so [no error] gold already does: $ gcc -fuse-ld=gold main.cpp libb.so /usr/bin/ld.gold: error: /tmp/ccg0cNpy.o: cannot make copy relocation for protected symbol 'internal_i', defined in libb.so collect2: error: ld returned 1 exit status
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.