public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] x86: Make protected symbols local for -shared
@ 2022-06-25 17:44 Fangrui Song
  2022-06-26 18:13 ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Fangrui Song @ 2022-06-25 17:44 UTC (permalink / raw)
  To: binutils, hjl.tools

Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
2 noticeable effects for -shared:

* GOT-generating relocations referencing a protected data symbol no
  longer lead to a GLOB_DAT (similar to a hidden symbol).
* Direct access relocations (e.g. R_X86_64_PC32) no longer has the
  confusing diagnostic below.

    __attribute__((visibility("protected"))) void *foo() {
      return (void *)foo;
    }

    // gcc -fpic -shared -fuse-ld=bfd
    relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object

The new behavior matches arm, aarch64 (commit
83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
linkers: gold and ld.lld.

Note: if some code tries to use direct access relocations to take the
address of foo, the pointer equality will break, but the error should be
reported on the executable link, not on the innocent shared object link.
glibc 2.36 will give a warning at relocation resolving time.

With this change, `#define elf_backend_extern_protected_data 1` is no
longer effective.  Just remove it.

Remove the test "Run protected-func-1 without PIE" since -fno-pic
address taken operation in the executable doesn't work with protected
symbol in a shared object by default.  Similarly, remove
protected-data-1a and protected-data-1b.  protected-data-1b can be made
working by removing HAVE_LD_PIE_COPYRELOC from GCC
(https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
---
 bfd/elf32-i386.c                      |  1 -
 bfd/elf64-x86-64.c                    |  1 -
 bfd/elfxx-x86.c                       |  2 +-
 ld/testsuite/ld-i386/protected1.d     |  4 +++-
 ld/testsuite/ld-i386/protected3.d     |  2 +-
 ld/testsuite/ld-i386/protected6a.d    |  4 +++-
 ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
 ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
 ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
 ld/testsuite/ld-x86-64/protected3.d   |  2 +-
 ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
 ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
 ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
 13 files changed, 24 insertions(+), 39 deletions(-)

diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index e4106d9fd3b..c3c46795731 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
 #define elf_backend_got_header_size	12
 #define elf_backend_plt_alignment	4
 #define elf_backend_dtrel_excludes_plt	1
-#define elf_backend_extern_protected_data 1
 #define elf_backend_caches_rawsize	1
 #define elf_backend_want_dynrelro	1
 
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 6154a70bdd7..aaa5f1496b9 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
 #define elf_backend_got_header_size	    (GOT_ENTRY_SIZE*3)
 #define elf_backend_rela_normal		    1
 #define elf_backend_plt_alignment	    4
-#define elf_backend_extern_protected_data   1
 #define elf_backend_caches_rawsize	    1
 #define elf_backend_dtrel_excludes_plt	    1
 #define elf_backend_want_dynrelro	    1
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index acb2cc8528d..18f3d335458 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
      2. When building executable, there is no dynamic linker.  Or
      3. or "-z nodynamic-undefined-weak" is used.
    */
-  if (SYMBOL_REFERENCES_LOCAL (info, h)
+  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
       || (h->root.type == bfd_link_hash_undefweak
 	  && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
 	      || (bfd_link_executable (info)
diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
index a3cb5cef140..531645b8fe8 100644
--- a/ld/testsuite/ld-i386/protected1.d
+++ b/ld/testsuite/ld-i386/protected1.d
@@ -1,3 +1,5 @@
 #as: --32
 #ld: -shared -melf_i386
-#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
+#readelf: -rW
+#...
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
index c3a6888d900..77367c4738f 100644
--- a/ld/testsuite/ld-i386/protected3.d
+++ b/ld/testsuite/ld-i386/protected3.d
@@ -8,7 +8,7 @@
 Disassembly of section .text:
 
 0+[a-f0-9]+ <bar>:
-[ 	]*[a-f0-9]+:	8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff    	mov    -0x[a-f0-9]+\(%ecx\),%eax
+[ 	]*[a-f0-9]+:	8d 81 00 00 00 00    	lea    0x0\(%ecx\),%eax
 [ 	]*[a-f0-9]+:	8b 00                	mov    \(%eax\),%eax
 [ 	]*[a-f0-9]+:	c3                   	ret
 #pass
diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
index 7dc350432f4..4d3873239f9 100644
--- a/ld/testsuite/ld-i386/protected6a.d
+++ b/ld/testsuite/ld-i386/protected6a.d
@@ -1,4 +1,6 @@
 #source: protected6.s
 #as: --32
 #ld: -shared -melf_i386
-#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
+#readelf: -rW
+#...
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
index 130611ddf49..1f49b655f7d 100644
--- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
+++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
@@ -1,4 +1,6 @@
 #source: pr24151a.s
 #as: --x32
 #ld: -shared -melf32_x86_64
-#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
+#readelf: -rW
+#...
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
index 783b85a1a6f..6c48e383e01 100644
--- a/ld/testsuite/ld-x86-64/pr24151a.d
+++ b/ld/testsuite/ld-x86-64/pr24151a.d
@@ -1,3 +1,5 @@
 #as: --64
 #ld: -shared -melf_x86_64
-#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
+#readelf: -rW
+#...
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
index 783b85a1a6f..6c48e383e01 100644
--- a/ld/testsuite/ld-x86-64/protected1.d
+++ b/ld/testsuite/ld-x86-64/protected1.d
@@ -1,3 +1,5 @@
 #as: --64
 #ld: -shared -melf_x86_64
-#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
+#readelf: -rW
+#...
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
index 57950e4d6b6..ba63991582f 100644
--- a/ld/testsuite/ld-x86-64/protected3.d
+++ b/ld/testsuite/ld-x86-64/protected3.d
@@ -8,7 +8,7 @@
 Disassembly of section .text:
 
 0+[a-f0-9]+ <bar>:
-[ 	]*[a-f0-9]+:	48 8b 05 ([0-9a-f]{2} ){4} *	mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
+[ 	]*[a-f0-9]+:	48 8d 05 ([0-9a-f]{2} ){4} *	lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
 [ 	]*[a-f0-9]+:	8b 00                	mov    \(%rax\),%eax
 [ 	]*[a-f0-9]+:	c3                   	ret
 #pass
diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
index 3a7963ffd2f..50d6430b577 100644
--- a/ld/testsuite/ld-x86-64/protected6a.d
+++ b/ld/testsuite/ld-x86-64/protected6a.d
@@ -1,4 +1,6 @@
 #source: protected6.s
 #as: --64
 #ld: -shared -melf_x86_64
-#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
+#readelf: -rW
+#...
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
index 3082084a7b8..3974246a2a8 100644
--- a/ld/testsuite/ld-x86-64/protected7a.d
+++ b/ld/testsuite/ld-x86-64/protected7a.d
@@ -1,4 +1,6 @@
 #source: protected7.s
 #as: --64
 #ld: -shared -melf_x86_64
-#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
+#readelf: -rW
+#...
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 5e5636bcebe..a096c0b9d0f 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
 	    "pr23997" \
 	    "pass.out" \
 	] \
-	[list \
-	    "Run protected-func-1 without PIE" \
-	    "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
-	    "-Wa,-mx86-used-note=yes" \
-	    { protected-func-1b.c } \
-	    "protected-func-1a" \
-	    "pass.out" \
-	    "$NOPIE_CFLAGS" \
-	] \
 	[list \
 	    "Run protected-func-1 with PIE" \
 	    "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
@@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
 	    "pass.out" \
 	    "-fPIE" \
 	] \
-	[list \
-	    "Run protected-data-1a without PIE" \
-	    "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
-	    "-Wa,-mx86-used-note=yes" \
-	    { protected-data-1b.c } \
-	    "protected-data-1a" \
-	    "pass.out" \
-	    "$NOPIE_CFLAGS" \
-	] \
-	[list \
-	    "Run protected-data-1b with PIE" \
-	    "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
-	    "-Wa,-mx86-used-note=yes" \
-	    { protected-data-1b.c } \
-	    "protected-data-1b" \
-	    "pass.out" \
-	    "-fPIE" \
-	] \
 	[list \
 	    "Run protected-data-2a without PIE" \
 	    "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
-- 
2.37


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-25 17:44 [PATCH] x86: Make protected symbols local for -shared Fangrui Song
@ 2022-06-26 18:13 ` H.J. Lu
  2022-06-26 19:03   ` Fangrui Song
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2022-06-26 18:13 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
>
> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
> 2 noticeable effects for -shared:
>
> * GOT-generating relocations referencing a protected data symbol no
>   longer lead to a GLOB_DAT (similar to a hidden symbol).
> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
>   confusing diagnostic below.
>
>     __attribute__((visibility("protected"))) void *foo() {
>       return (void *)foo;
>     }
>
>     // gcc -fpic -shared -fuse-ld=bfd
>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>
> The new behavior matches arm, aarch64 (commit
> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
> linkers: gold and ld.lld.
>
> Note: if some code tries to use direct access relocations to take the
> address of foo, the pointer equality will break, but the error should be
> reported on the executable link, not on the innocent shared object link.
> glibc 2.36 will give a warning at relocation resolving time.

It should be controlled by -z [no]indirect-extern-access.   Can you enable
-z  indirect-extern-access with -shared by default instead?

> With this change, `#define elf_backend_extern_protected_data 1` is no
> longer effective.  Just remove it.
>
> Remove the test "Run protected-func-1 without PIE" since -fno-pic
> address taken operation in the executable doesn't work with protected
> symbol in a shared object by default.  Similarly, remove
> protected-data-1a and protected-data-1b.  protected-data-1b can be made
> working by removing HAVE_LD_PIE_COPYRELOC from GCC
> (https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
> ---
>  bfd/elf32-i386.c                      |  1 -
>  bfd/elf64-x86-64.c                    |  1 -
>  bfd/elfxx-x86.c                       |  2 +-
>  ld/testsuite/ld-i386/protected1.d     |  4 +++-
>  ld/testsuite/ld-i386/protected3.d     |  2 +-
>  ld/testsuite/ld-i386/protected6a.d    |  4 +++-
>  ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
>  ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
>  ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
>  ld/testsuite/ld-x86-64/protected3.d   |  2 +-
>  ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
>  ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
>  ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
>  13 files changed, 24 insertions(+), 39 deletions(-)
>
> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> index e4106d9fd3b..c3c46795731 100644
> --- a/bfd/elf32-i386.c
> +++ b/bfd/elf32-i386.c
> @@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
>  #define elf_backend_got_header_size    12
>  #define elf_backend_plt_alignment      4
>  #define elf_backend_dtrel_excludes_plt 1
> -#define elf_backend_extern_protected_data 1
>  #define elf_backend_caches_rawsize     1
>  #define elf_backend_want_dynrelro      1
>
> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> index 6154a70bdd7..aaa5f1496b9 100644
> --- a/bfd/elf64-x86-64.c
> +++ b/bfd/elf64-x86-64.c
> @@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
>  #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
>  #define elf_backend_rela_normal                    1
>  #define elf_backend_plt_alignment          4
> -#define elf_backend_extern_protected_data   1
>  #define elf_backend_caches_rawsize         1
>  #define elf_backend_dtrel_excludes_plt     1
>  #define elf_backend_want_dynrelro          1
> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
> index acb2cc8528d..18f3d335458 100644
> --- a/bfd/elfxx-x86.c
> +++ b/bfd/elfxx-x86.c
> @@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
>       2. When building executable, there is no dynamic linker.  Or
>       3. or "-z nodynamic-undefined-weak" is used.
>     */
> -  if (SYMBOL_REFERENCES_LOCAL (info, h)
> +  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
>        || (h->root.type == bfd_link_hash_undefweak
>           && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
>               || (bfd_link_executable (info)
> diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
> index a3cb5cef140..531645b8fe8 100644
> --- a/ld/testsuite/ld-i386/protected1.d
> +++ b/ld/testsuite/ld-i386/protected1.d
> @@ -1,3 +1,5 @@
>  #as: --32
>  #ld: -shared -melf_i386
> -#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
> +#readelf: -rW
> +#...
> +There are no relocations in this file.
> diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
> index c3a6888d900..77367c4738f 100644
> --- a/ld/testsuite/ld-i386/protected3.d
> +++ b/ld/testsuite/ld-i386/protected3.d
> @@ -8,7 +8,7 @@
>  Disassembly of section .text:
>
>  0+[a-f0-9]+ <bar>:
> -[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
> +[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
>  [      ]*[a-f0-9]+:    c3                      ret
>  #pass
> diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
> index 7dc350432f4..4d3873239f9 100644
> --- a/ld/testsuite/ld-i386/protected6a.d
> +++ b/ld/testsuite/ld-i386/protected6a.d
> @@ -1,4 +1,6 @@
>  #source: protected6.s
>  #as: --32
>  #ld: -shared -melf_i386
> -#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
> +#readelf: -rW
> +#...
> +There are no relocations in this file.
> diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> index 130611ddf49..1f49b655f7d 100644
> --- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
> +++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> @@ -1,4 +1,6 @@
>  #source: pr24151a.s
>  #as: --x32
>  #ld: -shared -melf32_x86_64
> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> +#readelf: -rW
> +#...
> +There are no relocations in this file.
> diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
> index 783b85a1a6f..6c48e383e01 100644
> --- a/ld/testsuite/ld-x86-64/pr24151a.d
> +++ b/ld/testsuite/ld-x86-64/pr24151a.d
> @@ -1,3 +1,5 @@
>  #as: --64
>  #ld: -shared -melf_x86_64
> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> +#readelf: -rW
> +#...
> +There are no relocations in this file.
> diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
> index 783b85a1a6f..6c48e383e01 100644
> --- a/ld/testsuite/ld-x86-64/protected1.d
> +++ b/ld/testsuite/ld-x86-64/protected1.d
> @@ -1,3 +1,5 @@
>  #as: --64
>  #ld: -shared -melf_x86_64
> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> +#readelf: -rW
> +#...
> +There are no relocations in this file.
> diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
> index 57950e4d6b6..ba63991582f 100644
> --- a/ld/testsuite/ld-x86-64/protected3.d
> +++ b/ld/testsuite/ld-x86-64/protected3.d
> @@ -8,7 +8,7 @@
>  Disassembly of section .text:
>
>  0+[a-f0-9]+ <bar>:
> -[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> +[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
>  [      ]*[a-f0-9]+:    c3                      ret
>  #pass
> diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
> index 3a7963ffd2f..50d6430b577 100644
> --- a/ld/testsuite/ld-x86-64/protected6a.d
> +++ b/ld/testsuite/ld-x86-64/protected6a.d
> @@ -1,4 +1,6 @@
>  #source: protected6.s
>  #as: --64
>  #ld: -shared -melf_x86_64
> -#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
> +#readelf: -rW
> +#...
> +There are no relocations in this file.
> diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
> index 3082084a7b8..3974246a2a8 100644
> --- a/ld/testsuite/ld-x86-64/protected7a.d
> +++ b/ld/testsuite/ld-x86-64/protected7a.d
> @@ -1,4 +1,6 @@
>  #source: protected7.s
>  #as: --64
>  #ld: -shared -melf_x86_64
> -#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
> +#readelf: -rW
> +#...
> +There are no relocations in this file.
> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
> index 5e5636bcebe..a096c0b9d0f 100644
> --- a/ld/testsuite/ld-x86-64/x86-64.exp
> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
> @@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
>             "pr23997" \
>             "pass.out" \
>         ] \
> -       [list \
> -           "Run protected-func-1 without PIE" \
> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
> -           "-Wa,-mx86-used-note=yes" \
> -           { protected-func-1b.c } \
> -           "protected-func-1a" \
> -           "pass.out" \
> -           "$NOPIE_CFLAGS" \
> -       ] \
>         [list \
>             "Run protected-func-1 with PIE" \
>             "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
> @@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
>             "pass.out" \
>             "-fPIE" \
>         ] \
> -       [list \
> -           "Run protected-data-1a without PIE" \
> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
> -           "-Wa,-mx86-used-note=yes" \
> -           { protected-data-1b.c } \
> -           "protected-data-1a" \
> -           "pass.out" \
> -           "$NOPIE_CFLAGS" \
> -       ] \
> -       [list \
> -           "Run protected-data-1b with PIE" \
> -           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
> -           "-Wa,-mx86-used-note=yes" \
> -           { protected-data-1b.c } \
> -           "protected-data-1b" \
> -           "pass.out" \
> -           "-fPIE" \
> -       ] \
>         [list \
>             "Run protected-data-2a without PIE" \
>             "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
> --
> 2.37
>


-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-26 18:13 ` H.J. Lu
@ 2022-06-26 19:03   ` Fangrui Song
  2022-06-26 19:07     ` Fangrui Song
  2022-06-27 13:24     ` H.J. Lu
  0 siblings, 2 replies; 23+ messages in thread
From: Fangrui Song @ 2022-06-26 19:03 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On 2022-06-26, H.J. Lu wrote:
>On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
>>
>> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
>> 2 noticeable effects for -shared:
>>
>> * GOT-generating relocations referencing a protected data symbol no
>>   longer lead to a GLOB_DAT (similar to a hidden symbol).
>> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
>>   confusing diagnostic below.
>>
>>     __attribute__((visibility("protected"))) void *foo() {
>>       return (void *)foo;
>>     }
>>
>>     // gcc -fpic -shared -fuse-ld=bfd
>>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>>
>> The new behavior matches arm, aarch64 (commit
>> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
>> linkers: gold and ld.lld.
>>
>> Note: if some code tries to use direct access relocations to take the
>> address of foo, the pointer equality will break, but the error should be
>> reported on the executable link, not on the innocent shared object link.
>> glibc 2.36 will give a warning at relocation resolving time.
>
>It should be controlled by -z [no]indirect-extern-access.   Can you enable
>-z  indirect-extern-access with -shared by default instead?

If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
bfd/elf-properties.c:654 will create a
GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
This will probably be unexpected (and check-ld will have 280+ failures).

>> With this change, `#define elf_backend_extern_protected_data 1` is no
>> longer effective.  Just remove it.
>>
>> Remove the test "Run protected-func-1 without PIE" since -fno-pic
>> address taken operation in the executable doesn't work with protected
>> symbol in a shared object by default.  Similarly, remove
>> protected-data-1a and protected-data-1b.  protected-data-1b can be made
>> working by removing HAVE_LD_PIE_COPYRELOC from GCC
>> (https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
>> ---
>>  bfd/elf32-i386.c                      |  1 -
>>  bfd/elf64-x86-64.c                    |  1 -
>>  bfd/elfxx-x86.c                       |  2 +-
>>  ld/testsuite/ld-i386/protected1.d     |  4 +++-
>>  ld/testsuite/ld-i386/protected3.d     |  2 +-
>>  ld/testsuite/ld-i386/protected6a.d    |  4 +++-
>>  ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
>>  ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
>>  ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
>>  ld/testsuite/ld-x86-64/protected3.d   |  2 +-
>>  ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
>>  ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
>>  ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
>>  13 files changed, 24 insertions(+), 39 deletions(-)
>>
>> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
>> index e4106d9fd3b..c3c46795731 100644
>> --- a/bfd/elf32-i386.c
>> +++ b/bfd/elf32-i386.c
>> @@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
>>  #define elf_backend_got_header_size    12
>>  #define elf_backend_plt_alignment      4
>>  #define elf_backend_dtrel_excludes_plt 1
>> -#define elf_backend_extern_protected_data 1
>>  #define elf_backend_caches_rawsize     1
>>  #define elf_backend_want_dynrelro      1
>>
>> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
>> index 6154a70bdd7..aaa5f1496b9 100644
>> --- a/bfd/elf64-x86-64.c
>> +++ b/bfd/elf64-x86-64.c
>> @@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
>>  #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
>>  #define elf_backend_rela_normal                    1
>>  #define elf_backend_plt_alignment          4
>> -#define elf_backend_extern_protected_data   1
>>  #define elf_backend_caches_rawsize         1
>>  #define elf_backend_dtrel_excludes_plt     1
>>  #define elf_backend_want_dynrelro          1
>> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
>> index acb2cc8528d..18f3d335458 100644
>> --- a/bfd/elfxx-x86.c
>> +++ b/bfd/elfxx-x86.c
>> @@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
>>       2. When building executable, there is no dynamic linker.  Or
>>       3. or "-z nodynamic-undefined-weak" is used.
>>     */
>> -  if (SYMBOL_REFERENCES_LOCAL (info, h)
>> +  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
>>        || (h->root.type == bfd_link_hash_undefweak
>>           && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
>>               || (bfd_link_executable (info)
>> diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
>> index a3cb5cef140..531645b8fe8 100644
>> --- a/ld/testsuite/ld-i386/protected1.d
>> +++ b/ld/testsuite/ld-i386/protected1.d
>> @@ -1,3 +1,5 @@
>>  #as: --32
>>  #ld: -shared -melf_i386
>> -#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
>> +#readelf: -rW
>> +#...
>> +There are no relocations in this file.
>> diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
>> index c3a6888d900..77367c4738f 100644
>> --- a/ld/testsuite/ld-i386/protected3.d
>> +++ b/ld/testsuite/ld-i386/protected3.d
>> @@ -8,7 +8,7 @@
>>  Disassembly of section .text:
>>
>>  0+[a-f0-9]+ <bar>:
>> -[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
>> +[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
>>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
>>  [      ]*[a-f0-9]+:    c3                      ret
>>  #pass
>> diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
>> index 7dc350432f4..4d3873239f9 100644
>> --- a/ld/testsuite/ld-i386/protected6a.d
>> +++ b/ld/testsuite/ld-i386/protected6a.d
>> @@ -1,4 +1,6 @@
>>  #source: protected6.s
>>  #as: --32
>>  #ld: -shared -melf_i386
>> -#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
>> +#readelf: -rW
>> +#...
>> +There are no relocations in this file.
>> diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> index 130611ddf49..1f49b655f7d 100644
>> --- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> +++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> @@ -1,4 +1,6 @@
>>  #source: pr24151a.s
>>  #as: --x32
>>  #ld: -shared -melf32_x86_64
>> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> +#readelf: -rW
>> +#...
>> +There are no relocations in this file.
>> diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
>> index 783b85a1a6f..6c48e383e01 100644
>> --- a/ld/testsuite/ld-x86-64/pr24151a.d
>> +++ b/ld/testsuite/ld-x86-64/pr24151a.d
>> @@ -1,3 +1,5 @@
>>  #as: --64
>>  #ld: -shared -melf_x86_64
>> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> +#readelf: -rW
>> +#...
>> +There are no relocations in this file.
>> diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
>> index 783b85a1a6f..6c48e383e01 100644
>> --- a/ld/testsuite/ld-x86-64/protected1.d
>> +++ b/ld/testsuite/ld-x86-64/protected1.d
>> @@ -1,3 +1,5 @@
>>  #as: --64
>>  #ld: -shared -melf_x86_64
>> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> +#readelf: -rW
>> +#...
>> +There are no relocations in this file.
>> diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
>> index 57950e4d6b6..ba63991582f 100644
>> --- a/ld/testsuite/ld-x86-64/protected3.d
>> +++ b/ld/testsuite/ld-x86-64/protected3.d
>> @@ -8,7 +8,7 @@
>>  Disassembly of section .text:
>>
>>  0+[a-f0-9]+ <bar>:
>> -[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>> +[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
>>  [      ]*[a-f0-9]+:    c3                      ret
>>  #pass
>> diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
>> index 3a7963ffd2f..50d6430b577 100644
>> --- a/ld/testsuite/ld-x86-64/protected6a.d
>> +++ b/ld/testsuite/ld-x86-64/protected6a.d
>> @@ -1,4 +1,6 @@
>>  #source: protected6.s
>>  #as: --64
>>  #ld: -shared -melf_x86_64
>> -#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
>> +#readelf: -rW
>> +#...
>> +There are no relocations in this file.
>> diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
>> index 3082084a7b8..3974246a2a8 100644
>> --- a/ld/testsuite/ld-x86-64/protected7a.d
>> +++ b/ld/testsuite/ld-x86-64/protected7a.d
>> @@ -1,4 +1,6 @@
>>  #source: protected7.s
>>  #as: --64
>>  #ld: -shared -melf_x86_64
>> -#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
>> +#readelf: -rW
>> +#...
>> +There are no relocations in this file.
>> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
>> index 5e5636bcebe..a096c0b9d0f 100644
>> --- a/ld/testsuite/ld-x86-64/x86-64.exp
>> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
>> @@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
>>             "pr23997" \
>>             "pass.out" \
>>         ] \
>> -       [list \
>> -           "Run protected-func-1 without PIE" \
>> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
>> -           "-Wa,-mx86-used-note=yes" \
>> -           { protected-func-1b.c } \
>> -           "protected-func-1a" \
>> -           "pass.out" \
>> -           "$NOPIE_CFLAGS" \
>> -       ] \
>>         [list \
>>             "Run protected-func-1 with PIE" \
>>             "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
>> @@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
>>             "pass.out" \
>>             "-fPIE" \
>>         ] \
>> -       [list \
>> -           "Run protected-data-1a without PIE" \
>> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
>> -           "-Wa,-mx86-used-note=yes" \
>> -           { protected-data-1b.c } \
>> -           "protected-data-1a" \
>> -           "pass.out" \
>> -           "$NOPIE_CFLAGS" \
>> -       ] \
>> -       [list \
>> -           "Run protected-data-1b with PIE" \
>> -           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
>> -           "-Wa,-mx86-used-note=yes" \
>> -           { protected-data-1b.c } \
>> -           "protected-data-1b" \
>> -           "pass.out" \
>> -           "-fPIE" \
>> -       ] \
>>         [list \
>>             "Run protected-data-2a without PIE" \
>>             "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
>> --
>> 2.37
>>
>
>
>-- 
>H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-26 19:03   ` Fangrui Song
@ 2022-06-26 19:07     ` Fangrui Song
  2022-06-27 13:30       ` H.J. Lu
  2022-06-27 13:24     ` H.J. Lu
  1 sibling, 1 reply; 23+ messages in thread
From: Fangrui Song @ 2022-06-26 19:07 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On 2022-06-26, Fangrui Song wrote:
>On 2022-06-26, H.J. Lu wrote:
>>On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
>>>
>>>Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
>>>2 noticeable effects for -shared:
>>>
>>>* GOT-generating relocations referencing a protected data symbol no
>>>  longer lead to a GLOB_DAT (similar to a hidden symbol).
>>>* Direct access relocations (e.g. R_X86_64_PC32) no longer has the
>>>  confusing diagnostic below.
>>>
>>>    __attribute__((visibility("protected"))) void *foo() {
>>>      return (void *)foo;
>>>    }
>>>
>>>    // gcc -fpic -shared -fuse-ld=bfd
>>>    relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>>>
>>>The new behavior matches arm, aarch64 (commit
>>>83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
>>>linkers: gold and ld.lld.
>>>
>>>Note: if some code tries to use direct access relocations to take the
>>>address of foo, the pointer equality will break, but the error should be
>>>reported on the executable link, not on the innocent shared object link.
>>>glibc 2.36 will give a warning at relocation resolving time.
>>
>>It should be controlled by -z [no]indirect-extern-access.   Can you enable
>>-z  indirect-extern-access with -shared by default instead?
>
>If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
>bfd/elf-properties.c:654 will create a
>GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
>This will probably be unexpected (and check-ld will have 280+ failures).

By removing elf_backend_extern_protected_data as in the current patch,
no port will use elf_backend_extern_protected_data. We can just remove
elf_backend_extern_protected_data, and probably make -z (no)?extern-protected-data 
ignored options in the future (I believe nobody uses this option).

>>>With this change, `#define elf_backend_extern_protected_data 1` is no
>>>longer effective.  Just remove it.
>>>
>>>Remove the test "Run protected-func-1 without PIE" since -fno-pic
>>>address taken operation in the executable doesn't work with protected
>>>symbol in a shared object by default.  Similarly, remove
>>>protected-data-1a and protected-data-1b.  protected-data-1b can be made
>>>working by removing HAVE_LD_PIE_COPYRELOC from GCC
>>>(https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
>>>---
>>> bfd/elf32-i386.c                      |  1 -
>>> bfd/elf64-x86-64.c                    |  1 -
>>> bfd/elfxx-x86.c                       |  2 +-
>>> ld/testsuite/ld-i386/protected1.d     |  4 +++-
>>> ld/testsuite/ld-i386/protected3.d     |  2 +-
>>> ld/testsuite/ld-i386/protected6a.d    |  4 +++-
>>> ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
>>> ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
>>> ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
>>> ld/testsuite/ld-x86-64/protected3.d   |  2 +-
>>> ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
>>> ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
>>> ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
>>> 13 files changed, 24 insertions(+), 39 deletions(-)
>>>
>>>diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
>>>index e4106d9fd3b..c3c46795731 100644
>>>--- a/bfd/elf32-i386.c
>>>+++ b/bfd/elf32-i386.c
>>>@@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
>>> #define elf_backend_got_header_size    12
>>> #define elf_backend_plt_alignment      4
>>> #define elf_backend_dtrel_excludes_plt 1
>>>-#define elf_backend_extern_protected_data 1
>>> #define elf_backend_caches_rawsize     1
>>> #define elf_backend_want_dynrelro      1
>>>
>>>diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
>>>index 6154a70bdd7..aaa5f1496b9 100644
>>>--- a/bfd/elf64-x86-64.c
>>>+++ b/bfd/elf64-x86-64.c
>>>@@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
>>> #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
>>> #define elf_backend_rela_normal                    1
>>> #define elf_backend_plt_alignment          4
>>>-#define elf_backend_extern_protected_data   1
>>> #define elf_backend_caches_rawsize         1
>>> #define elf_backend_dtrel_excludes_plt     1
>>> #define elf_backend_want_dynrelro          1
>>>diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
>>>index acb2cc8528d..18f3d335458 100644
>>>--- a/bfd/elfxx-x86.c
>>>+++ b/bfd/elfxx-x86.c
>>>@@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
>>>      2. When building executable, there is no dynamic linker.  Or
>>>      3. or "-z nodynamic-undefined-weak" is used.
>>>    */
>>>-  if (SYMBOL_REFERENCES_LOCAL (info, h)
>>>+  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
>>>       || (h->root.type == bfd_link_hash_undefweak
>>>          && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
>>>              || (bfd_link_executable (info)
>>>diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
>>>index a3cb5cef140..531645b8fe8 100644
>>>--- a/ld/testsuite/ld-i386/protected1.d
>>>+++ b/ld/testsuite/ld-i386/protected1.d
>>>@@ -1,3 +1,5 @@
>>> #as: --32
>>> #ld: -shared -melf_i386
>>>-#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
>>>+#readelf: -rW
>>>+#...
>>>+There are no relocations in this file.
>>>diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
>>>index c3a6888d900..77367c4738f 100644
>>>--- a/ld/testsuite/ld-i386/protected3.d
>>>+++ b/ld/testsuite/ld-i386/protected3.d
>>>@@ -8,7 +8,7 @@
>>> Disassembly of section .text:
>>>
>>> 0+[a-f0-9]+ <bar>:
>>>-[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
>>>+[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
>>> [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
>>> [      ]*[a-f0-9]+:    c3                      ret
>>> #pass
>>>diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
>>>index 7dc350432f4..4d3873239f9 100644
>>>--- a/ld/testsuite/ld-i386/protected6a.d
>>>+++ b/ld/testsuite/ld-i386/protected6a.d
>>>@@ -1,4 +1,6 @@
>>> #source: protected6.s
>>> #as: --32
>>> #ld: -shared -melf_i386
>>>-#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
>>>+#readelf: -rW
>>>+#...
>>>+There are no relocations in this file.
>>>diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>>>index 130611ddf49..1f49b655f7d 100644
>>>--- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
>>>+++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>>>@@ -1,4 +1,6 @@
>>> #source: pr24151a.s
>>> #as: --x32
>>> #ld: -shared -melf32_x86_64
>>>-#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>>>+#readelf: -rW
>>>+#...
>>>+There are no relocations in this file.
>>>diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
>>>index 783b85a1a6f..6c48e383e01 100644
>>>--- a/ld/testsuite/ld-x86-64/pr24151a.d
>>>+++ b/ld/testsuite/ld-x86-64/pr24151a.d
>>>@@ -1,3 +1,5 @@
>>> #as: --64
>>> #ld: -shared -melf_x86_64
>>>-#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>>>+#readelf: -rW
>>>+#...
>>>+There are no relocations in this file.
>>>diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
>>>index 783b85a1a6f..6c48e383e01 100644
>>>--- a/ld/testsuite/ld-x86-64/protected1.d
>>>+++ b/ld/testsuite/ld-x86-64/protected1.d
>>>@@ -1,3 +1,5 @@
>>> #as: --64
>>> #ld: -shared -melf_x86_64
>>>-#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>>>+#readelf: -rW
>>>+#...
>>>+There are no relocations in this file.
>>>diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
>>>index 57950e4d6b6..ba63991582f 100644
>>>--- a/ld/testsuite/ld-x86-64/protected3.d
>>>+++ b/ld/testsuite/ld-x86-64/protected3.d
>>>@@ -8,7 +8,7 @@
>>> Disassembly of section .text:
>>>
>>> 0+[a-f0-9]+ <bar>:
>>>-[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>>>+[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>>> [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
>>> [      ]*[a-f0-9]+:    c3                      ret
>>> #pass
>>>diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
>>>index 3a7963ffd2f..50d6430b577 100644
>>>--- a/ld/testsuite/ld-x86-64/protected6a.d
>>>+++ b/ld/testsuite/ld-x86-64/protected6a.d
>>>@@ -1,4 +1,6 @@
>>> #source: protected6.s
>>> #as: --64
>>> #ld: -shared -melf_x86_64
>>>-#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
>>>+#readelf: -rW
>>>+#...
>>>+There are no relocations in this file.
>>>diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
>>>index 3082084a7b8..3974246a2a8 100644
>>>--- a/ld/testsuite/ld-x86-64/protected7a.d
>>>+++ b/ld/testsuite/ld-x86-64/protected7a.d
>>>@@ -1,4 +1,6 @@
>>> #source: protected7.s
>>> #as: --64
>>> #ld: -shared -melf_x86_64
>>>-#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
>>>+#readelf: -rW
>>>+#...
>>>+There are no relocations in this file.
>>>diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
>>>index 5e5636bcebe..a096c0b9d0f 100644
>>>--- a/ld/testsuite/ld-x86-64/x86-64.exp
>>>+++ b/ld/testsuite/ld-x86-64/x86-64.exp
>>>@@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
>>>            "pr23997" \
>>>            "pass.out" \
>>>        ] \
>>>-       [list \
>>>-           "Run protected-func-1 without PIE" \
>>>-           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
>>>-           "-Wa,-mx86-used-note=yes" \
>>>-           { protected-func-1b.c } \
>>>-           "protected-func-1a" \
>>>-           "pass.out" \
>>>-           "$NOPIE_CFLAGS" \
>>>-       ] \
>>>        [list \
>>>            "Run protected-func-1 with PIE" \
>>>            "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
>>>@@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
>>>            "pass.out" \
>>>            "-fPIE" \
>>>        ] \
>>>-       [list \
>>>-           "Run protected-data-1a without PIE" \
>>>-           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
>>>-           "-Wa,-mx86-used-note=yes" \
>>>-           { protected-data-1b.c } \
>>>-           "protected-data-1a" \
>>>-           "pass.out" \
>>>-           "$NOPIE_CFLAGS" \
>>>-       ] \
>>>-       [list \
>>>-           "Run protected-data-1b with PIE" \
>>>-           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
>>>-           "-Wa,-mx86-used-note=yes" \
>>>-           { protected-data-1b.c } \
>>>-           "protected-data-1b" \
>>>-           "pass.out" \
>>>-           "-fPIE" \
>>>-       ] \
>>>        [list \
>>>            "Run protected-data-2a without PIE" \
>>>            "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
>>>--
>>>2.37
>>>
>>
>>
>>-- 
>>H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-26 19:03   ` Fangrui Song
  2022-06-26 19:07     ` Fangrui Song
@ 2022-06-27 13:24     ` H.J. Lu
  2022-06-27 17:09       ` Fangrui Song
  1 sibling, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2022-06-27 13:24 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
>
> On 2022-06-26, H.J. Lu wrote:
> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
> >>
> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
> >> 2 noticeable effects for -shared:
> >>
> >> * GOT-generating relocations referencing a protected data symbol no
> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
> >>   confusing diagnostic below.
> >>
> >>     __attribute__((visibility("protected"))) void *foo() {
> >>       return (void *)foo;
> >>     }
> >>
> >>     // gcc -fpic -shared -fuse-ld=bfd
> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >>
> >> The new behavior matches arm, aarch64 (commit
> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
> >> linkers: gold and ld.lld.
> >>
> >> Note: if some code tries to use direct access relocations to take the
> >> address of foo, the pointer equality will break, but the error should be
> >> reported on the executable link, not on the innocent shared object link.
> >> glibc 2.36 will give a warning at relocation resolving time.
> >
> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
> >-z  indirect-extern-access with -shared by default instead?
>
> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
> bfd/elf-properties.c:654 will create a
> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
> This will probably be unexpected (and check-ld will have 280+ failures).

This is normal when the default behavior is changed.  You can pass
-z noindirect-extern-access to these testcases.

> >> With this change, `#define elf_backend_extern_protected_data 1` is no
> >> longer effective.  Just remove it.
> >>
> >> Remove the test "Run protected-func-1 without PIE" since -fno-pic
> >> address taken operation in the executable doesn't work with protected
> >> symbol in a shared object by default.  Similarly, remove
> >> protected-data-1a and protected-data-1b.  protected-data-1b can be made
> >> working by removing HAVE_LD_PIE_COPYRELOC from GCC
> >> (https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
> >> ---
> >>  bfd/elf32-i386.c                      |  1 -
> >>  bfd/elf64-x86-64.c                    |  1 -
> >>  bfd/elfxx-x86.c                       |  2 +-
> >>  ld/testsuite/ld-i386/protected1.d     |  4 +++-
> >>  ld/testsuite/ld-i386/protected3.d     |  2 +-
> >>  ld/testsuite/ld-i386/protected6a.d    |  4 +++-
> >>  ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
> >>  ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
> >>  ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
> >>  ld/testsuite/ld-x86-64/protected3.d   |  2 +-
> >>  ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
> >>  ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
> >>  ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
> >>  13 files changed, 24 insertions(+), 39 deletions(-)
> >>
> >> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> >> index e4106d9fd3b..c3c46795731 100644
> >> --- a/bfd/elf32-i386.c
> >> +++ b/bfd/elf32-i386.c
> >> @@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
> >>  #define elf_backend_got_header_size    12
> >>  #define elf_backend_plt_alignment      4
> >>  #define elf_backend_dtrel_excludes_plt 1
> >> -#define elf_backend_extern_protected_data 1
> >>  #define elf_backend_caches_rawsize     1
> >>  #define elf_backend_want_dynrelro      1
> >>
> >> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> >> index 6154a70bdd7..aaa5f1496b9 100644
> >> --- a/bfd/elf64-x86-64.c
> >> +++ b/bfd/elf64-x86-64.c
> >> @@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
> >>  #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
> >>  #define elf_backend_rela_normal                    1
> >>  #define elf_backend_plt_alignment          4
> >> -#define elf_backend_extern_protected_data   1
> >>  #define elf_backend_caches_rawsize         1
> >>  #define elf_backend_dtrel_excludes_plt     1
> >>  #define elf_backend_want_dynrelro          1
> >> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
> >> index acb2cc8528d..18f3d335458 100644
> >> --- a/bfd/elfxx-x86.c
> >> +++ b/bfd/elfxx-x86.c
> >> @@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
> >>       2. When building executable, there is no dynamic linker.  Or
> >>       3. or "-z nodynamic-undefined-weak" is used.
> >>     */
> >> -  if (SYMBOL_REFERENCES_LOCAL (info, h)
> >> +  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
> >>        || (h->root.type == bfd_link_hash_undefweak
> >>           && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
> >>               || (bfd_link_executable (info)
> >> diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
> >> index a3cb5cef140..531645b8fe8 100644
> >> --- a/ld/testsuite/ld-i386/protected1.d
> >> +++ b/ld/testsuite/ld-i386/protected1.d
> >> @@ -1,3 +1,5 @@
> >>  #as: --32
> >>  #ld: -shared -melf_i386
> >> -#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
> >> +#readelf: -rW
> >> +#...
> >> +There are no relocations in this file.
> >> diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
> >> index c3a6888d900..77367c4738f 100644
> >> --- a/ld/testsuite/ld-i386/protected3.d
> >> +++ b/ld/testsuite/ld-i386/protected3.d
> >> @@ -8,7 +8,7 @@
> >>  Disassembly of section .text:
> >>
> >>  0+[a-f0-9]+ <bar>:
> >> -[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
> >> +[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
> >>  [      ]*[a-f0-9]+:    c3                      ret
> >>  #pass
> >> diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
> >> index 7dc350432f4..4d3873239f9 100644
> >> --- a/ld/testsuite/ld-i386/protected6a.d
> >> +++ b/ld/testsuite/ld-i386/protected6a.d
> >> @@ -1,4 +1,6 @@
> >>  #source: protected6.s
> >>  #as: --32
> >>  #ld: -shared -melf_i386
> >> -#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
> >> +#readelf: -rW
> >> +#...
> >> +There are no relocations in this file.
> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> index 130611ddf49..1f49b655f7d 100644
> >> --- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> +++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> @@ -1,4 +1,6 @@
> >>  #source: pr24151a.s
> >>  #as: --x32
> >>  #ld: -shared -melf32_x86_64
> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> +#readelf: -rW
> >> +#...
> >> +There are no relocations in this file.
> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
> >> index 783b85a1a6f..6c48e383e01 100644
> >> --- a/ld/testsuite/ld-x86-64/pr24151a.d
> >> +++ b/ld/testsuite/ld-x86-64/pr24151a.d
> >> @@ -1,3 +1,5 @@
> >>  #as: --64
> >>  #ld: -shared -melf_x86_64
> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> +#readelf: -rW
> >> +#...
> >> +There are no relocations in this file.
> >> diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
> >> index 783b85a1a6f..6c48e383e01 100644
> >> --- a/ld/testsuite/ld-x86-64/protected1.d
> >> +++ b/ld/testsuite/ld-x86-64/protected1.d
> >> @@ -1,3 +1,5 @@
> >>  #as: --64
> >>  #ld: -shared -melf_x86_64
> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> +#readelf: -rW
> >> +#...
> >> +There are no relocations in this file.
> >> diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
> >> index 57950e4d6b6..ba63991582f 100644
> >> --- a/ld/testsuite/ld-x86-64/protected3.d
> >> +++ b/ld/testsuite/ld-x86-64/protected3.d
> >> @@ -8,7 +8,7 @@
> >>  Disassembly of section .text:
> >>
> >>  0+[a-f0-9]+ <bar>:
> >> -[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> >> +[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
> >>  [      ]*[a-f0-9]+:    c3                      ret
> >>  #pass
> >> diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
> >> index 3a7963ffd2f..50d6430b577 100644
> >> --- a/ld/testsuite/ld-x86-64/protected6a.d
> >> +++ b/ld/testsuite/ld-x86-64/protected6a.d
> >> @@ -1,4 +1,6 @@
> >>  #source: protected6.s
> >>  #as: --64
> >>  #ld: -shared -melf_x86_64
> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
> >> +#readelf: -rW
> >> +#...
> >> +There are no relocations in this file.
> >> diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
> >> index 3082084a7b8..3974246a2a8 100644
> >> --- a/ld/testsuite/ld-x86-64/protected7a.d
> >> +++ b/ld/testsuite/ld-x86-64/protected7a.d
> >> @@ -1,4 +1,6 @@
> >>  #source: protected7.s
> >>  #as: --64
> >>  #ld: -shared -melf_x86_64
> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
> >> +#readelf: -rW
> >> +#...
> >> +There are no relocations in this file.
> >> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
> >> index 5e5636bcebe..a096c0b9d0f 100644
> >> --- a/ld/testsuite/ld-x86-64/x86-64.exp
> >> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
> >> @@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
> >>             "pr23997" \
> >>             "pass.out" \
> >>         ] \
> >> -       [list \
> >> -           "Run protected-func-1 without PIE" \
> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
> >> -           "-Wa,-mx86-used-note=yes" \
> >> -           { protected-func-1b.c } \
> >> -           "protected-func-1a" \
> >> -           "pass.out" \
> >> -           "$NOPIE_CFLAGS" \
> >> -       ] \
> >>         [list \
> >>             "Run protected-func-1 with PIE" \
> >>             "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
> >> @@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
> >>             "pass.out" \
> >>             "-fPIE" \
> >>         ] \
> >> -       [list \
> >> -           "Run protected-data-1a without PIE" \
> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
> >> -           "-Wa,-mx86-used-note=yes" \
> >> -           { protected-data-1b.c } \
> >> -           "protected-data-1a" \
> >> -           "pass.out" \
> >> -           "$NOPIE_CFLAGS" \
> >> -       ] \
> >> -       [list \
> >> -           "Run protected-data-1b with PIE" \
> >> -           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
> >> -           "-Wa,-mx86-used-note=yes" \
> >> -           { protected-data-1b.c } \
> >> -           "protected-data-1b" \
> >> -           "pass.out" \
> >> -           "-fPIE" \
> >> -       ] \
> >>         [list \
> >>             "Run protected-data-2a without PIE" \
> >>             "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
> >> --
> >> 2.37
> >>
> >
> >
> >--
> >H.J.



-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-26 19:07     ` Fangrui Song
@ 2022-06-27 13:30       ` H.J. Lu
  0 siblings, 0 replies; 23+ messages in thread
From: H.J. Lu @ 2022-06-27 13:30 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

On Sun, Jun 26, 2022 at 12:07 PM Fangrui Song <i@maskray.me> wrote:
>
> On 2022-06-26, Fangrui Song wrote:
> >On 2022-06-26, H.J. Lu wrote:
> >>On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
> >>>
> >>>Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
> >>>2 noticeable effects for -shared:
> >>>
> >>>* GOT-generating relocations referencing a protected data symbol no
> >>>  longer lead to a GLOB_DAT (similar to a hidden symbol).
> >>>* Direct access relocations (e.g. R_X86_64_PC32) no longer has the
> >>>  confusing diagnostic below.
> >>>
> >>>    __attribute__((visibility("protected"))) void *foo() {
> >>>      return (void *)foo;
> >>>    }
> >>>
> >>>    // gcc -fpic -shared -fuse-ld=bfd
> >>>    relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >>>
> >>>The new behavior matches arm, aarch64 (commit
> >>>83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
> >>>linkers: gold and ld.lld.
> >>>
> >>>Note: if some code tries to use direct access relocations to take the
> >>>address of foo, the pointer equality will break, but the error should be
> >>>reported on the executable link, not on the innocent shared object link.
> >>>glibc 2.36 will give a warning at relocation resolving time.
> >>
> >>It should be controlled by -z [no]indirect-extern-access.   Can you enable
> >>-z  indirect-extern-access with -shared by default instead?
> >
> >If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
> >bfd/elf-properties.c:654 will create a
> >GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
> >This will probably be unexpected (and check-ld will have 280+ failures).
>
> By removing elf_backend_extern_protected_data as in the current patch,
> no port will use elf_backend_extern_protected_data. We can just remove
> elf_backend_extern_protected_data, and probably make -z (no)?extern-protected-data
> ignored options in the future (I believe nobody uses this option).

-z noindirect-extern-access also uses it.

> >>>With this change, `#define elf_backend_extern_protected_data 1` is no
> >>>longer effective.  Just remove it.
> >>>
> >>>Remove the test "Run protected-func-1 without PIE" since -fno-pic
> >>>address taken operation in the executable doesn't work with protected
> >>>symbol in a shared object by default.  Similarly, remove
> >>>protected-data-1a and protected-data-1b.  protected-data-1b can be made
> >>>working by removing HAVE_LD_PIE_COPYRELOC from GCC
> >>>(https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
> >>>---
> >>> bfd/elf32-i386.c                      |  1 -
> >>> bfd/elf64-x86-64.c                    |  1 -
> >>> bfd/elfxx-x86.c                       |  2 +-
> >>> ld/testsuite/ld-i386/protected1.d     |  4 +++-
> >>> ld/testsuite/ld-i386/protected3.d     |  2 +-
> >>> ld/testsuite/ld-i386/protected6a.d    |  4 +++-
> >>> ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
> >>> ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
> >>> ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
> >>> ld/testsuite/ld-x86-64/protected3.d   |  2 +-
> >>> ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
> >>> ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
> >>> ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
> >>> 13 files changed, 24 insertions(+), 39 deletions(-)
> >>>
> >>>diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> >>>index e4106d9fd3b..c3c46795731 100644
> >>>--- a/bfd/elf32-i386.c
> >>>+++ b/bfd/elf32-i386.c
> >>>@@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
> >>> #define elf_backend_got_header_size    12
> >>> #define elf_backend_plt_alignment      4
> >>> #define elf_backend_dtrel_excludes_plt 1
> >>>-#define elf_backend_extern_protected_data 1
> >>> #define elf_backend_caches_rawsize     1
> >>> #define elf_backend_want_dynrelro      1
> >>>
> >>>diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> >>>index 6154a70bdd7..aaa5f1496b9 100644
> >>>--- a/bfd/elf64-x86-64.c
> >>>+++ b/bfd/elf64-x86-64.c
> >>>@@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
> >>> #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
> >>> #define elf_backend_rela_normal                    1
> >>> #define elf_backend_plt_alignment          4
> >>>-#define elf_backend_extern_protected_data   1
> >>> #define elf_backend_caches_rawsize         1
> >>> #define elf_backend_dtrel_excludes_plt     1
> >>> #define elf_backend_want_dynrelro          1
> >>>diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
> >>>index acb2cc8528d..18f3d335458 100644
> >>>--- a/bfd/elfxx-x86.c
> >>>+++ b/bfd/elfxx-x86.c
> >>>@@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
> >>>      2. When building executable, there is no dynamic linker.  Or
> >>>      3. or "-z nodynamic-undefined-weak" is used.
> >>>    */
> >>>-  if (SYMBOL_REFERENCES_LOCAL (info, h)
> >>>+  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
> >>>       || (h->root.type == bfd_link_hash_undefweak
> >>>          && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
> >>>              || (bfd_link_executable (info)
> >>>diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
> >>>index a3cb5cef140..531645b8fe8 100644
> >>>--- a/ld/testsuite/ld-i386/protected1.d
> >>>+++ b/ld/testsuite/ld-i386/protected1.d
> >>>@@ -1,3 +1,5 @@
> >>> #as: --32
> >>> #ld: -shared -melf_i386
> >>>-#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
> >>>+#readelf: -rW
> >>>+#...
> >>>+There are no relocations in this file.
> >>>diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
> >>>index c3a6888d900..77367c4738f 100644
> >>>--- a/ld/testsuite/ld-i386/protected3.d
> >>>+++ b/ld/testsuite/ld-i386/protected3.d
> >>>@@ -8,7 +8,7 @@
> >>> Disassembly of section .text:
> >>>
> >>> 0+[a-f0-9]+ <bar>:
> >>>-[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
> >>>+[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
> >>> [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
> >>> [      ]*[a-f0-9]+:    c3                      ret
> >>> #pass
> >>>diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
> >>>index 7dc350432f4..4d3873239f9 100644
> >>>--- a/ld/testsuite/ld-i386/protected6a.d
> >>>+++ b/ld/testsuite/ld-i386/protected6a.d
> >>>@@ -1,4 +1,6 @@
> >>> #source: protected6.s
> >>> #as: --32
> >>> #ld: -shared -melf_i386
> >>>-#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
> >>>+#readelf: -rW
> >>>+#...
> >>>+There are no relocations in this file.
> >>>diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >>>index 130611ddf49..1f49b655f7d 100644
> >>>--- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >>>+++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >>>@@ -1,4 +1,6 @@
> >>> #source: pr24151a.s
> >>> #as: --x32
> >>> #ld: -shared -melf32_x86_64
> >>>-#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >>>+#readelf: -rW
> >>>+#...
> >>>+There are no relocations in this file.
> >>>diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
> >>>index 783b85a1a6f..6c48e383e01 100644
> >>>--- a/ld/testsuite/ld-x86-64/pr24151a.d
> >>>+++ b/ld/testsuite/ld-x86-64/pr24151a.d
> >>>@@ -1,3 +1,5 @@
> >>> #as: --64
> >>> #ld: -shared -melf_x86_64
> >>>-#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >>>+#readelf: -rW
> >>>+#...
> >>>+There are no relocations in this file.
> >>>diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
> >>>index 783b85a1a6f..6c48e383e01 100644
> >>>--- a/ld/testsuite/ld-x86-64/protected1.d
> >>>+++ b/ld/testsuite/ld-x86-64/protected1.d
> >>>@@ -1,3 +1,5 @@
> >>> #as: --64
> >>> #ld: -shared -melf_x86_64
> >>>-#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >>>+#readelf: -rW
> >>>+#...
> >>>+There are no relocations in this file.
> >>>diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
> >>>index 57950e4d6b6..ba63991582f 100644
> >>>--- a/ld/testsuite/ld-x86-64/protected3.d
> >>>+++ b/ld/testsuite/ld-x86-64/protected3.d
> >>>@@ -8,7 +8,7 @@
> >>> Disassembly of section .text:
> >>>
> >>> 0+[a-f0-9]+ <bar>:
> >>>-[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> >>>+[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> >>> [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
> >>> [      ]*[a-f0-9]+:    c3                      ret
> >>> #pass
> >>>diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
> >>>index 3a7963ffd2f..50d6430b577 100644
> >>>--- a/ld/testsuite/ld-x86-64/protected6a.d
> >>>+++ b/ld/testsuite/ld-x86-64/protected6a.d
> >>>@@ -1,4 +1,6 @@
> >>> #source: protected6.s
> >>> #as: --64
> >>> #ld: -shared -melf_x86_64
> >>>-#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
> >>>+#readelf: -rW
> >>>+#...
> >>>+There are no relocations in this file.
> >>>diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
> >>>index 3082084a7b8..3974246a2a8 100644
> >>>--- a/ld/testsuite/ld-x86-64/protected7a.d
> >>>+++ b/ld/testsuite/ld-x86-64/protected7a.d
> >>>@@ -1,4 +1,6 @@
> >>> #source: protected7.s
> >>> #as: --64
> >>> #ld: -shared -melf_x86_64
> >>>-#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
> >>>+#readelf: -rW
> >>>+#...
> >>>+There are no relocations in this file.
> >>>diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
> >>>index 5e5636bcebe..a096c0b9d0f 100644
> >>>--- a/ld/testsuite/ld-x86-64/x86-64.exp
> >>>+++ b/ld/testsuite/ld-x86-64/x86-64.exp
> >>>@@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
> >>>            "pr23997" \
> >>>            "pass.out" \
> >>>        ] \
> >>>-       [list \
> >>>-           "Run protected-func-1 without PIE" \
> >>>-           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
> >>>-           "-Wa,-mx86-used-note=yes" \
> >>>-           { protected-func-1b.c } \
> >>>-           "protected-func-1a" \
> >>>-           "pass.out" \
> >>>-           "$NOPIE_CFLAGS" \
> >>>-       ] \
> >>>        [list \
> >>>            "Run protected-func-1 with PIE" \
> >>>            "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
> >>>@@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
> >>>            "pass.out" \
> >>>            "-fPIE" \
> >>>        ] \
> >>>-       [list \
> >>>-           "Run protected-data-1a without PIE" \
> >>>-           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
> >>>-           "-Wa,-mx86-used-note=yes" \
> >>>-           { protected-data-1b.c } \
> >>>-           "protected-data-1a" \
> >>>-           "pass.out" \
> >>>-           "$NOPIE_CFLAGS" \
> >>>-       ] \
> >>>-       [list \
> >>>-           "Run protected-data-1b with PIE" \
> >>>-           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
> >>>-           "-Wa,-mx86-used-note=yes" \
> >>>-           { protected-data-1b.c } \
> >>>-           "protected-data-1b" \
> >>>-           "pass.out" \
> >>>-           "-fPIE" \
> >>>-       ] \
> >>>        [list \
> >>>            "Run protected-data-2a without PIE" \
> >>>            "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
> >>>--
> >>>2.37
> >>>
> >>
> >>
> >>--
> >>H.J.



-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-27 13:24     ` H.J. Lu
@ 2022-06-27 17:09       ` Fangrui Song
  2022-06-27 17:43         ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Fangrui Song @ 2022-06-27 17:09 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On 2022-06-27, H.J. Lu wrote:
>On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
>>
>> On 2022-06-26, H.J. Lu wrote:
>> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
>> >>
>> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
>> >> 2 noticeable effects for -shared:
>> >>
>> >> * GOT-generating relocations referencing a protected data symbol no
>> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
>> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
>> >>   confusing diagnostic below.
>> >>
>> >>     __attribute__((visibility("protected"))) void *foo() {
>> >>       return (void *)foo;
>> >>     }
>> >>
>> >>     // gcc -fpic -shared -fuse-ld=bfd
>> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >>
>> >> The new behavior matches arm, aarch64 (commit
>> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
>> >> linkers: gold and ld.lld.
>> >>
>> >> Note: if some code tries to use direct access relocations to take the
>> >> address of foo, the pointer equality will break, but the error should be
>> >> reported on the executable link, not on the innocent shared object link.
>> >> glibc 2.36 will give a warning at relocation resolving time.
>> >
>> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
>> >-z  indirect-extern-access with -shared by default instead?
>>
>> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
>> bfd/elf-properties.c:654 will create a
>> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
>> This will probably be unexpected (and check-ld will have 280+ failures).
>
>This is normal when the default behavior is changed.  You can pass
>-z noindirect-extern-access to these testcases.

Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
significant behavior change and may unnecessarily break user programs
(glibc will report an error instead of a warning).

If the executable takes the address of a protected function defined in a
shared object, it may or may not cause a pointer equality problem (the
shared object may not take the address) and the problem (if exists) may or
may not be a broken invariance to the program (it may not expect pointer
equality).

All of aarch64/arm/powerpc64/riscv (likely most except x86, but I
haven't enumerated) consider a protected data symbol local in -shared
links. x86 did so a while ago (before 2015?).  (For
aarch64/arm/powerpc64/riscv, I wish that we never need
GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. The property will just
waste some bytes in every shared object without carrying much
information.)

The 280+ failures in check-ld due to the default
GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS need to be considered as
well.

>> >> With this change, `#define elf_backend_extern_protected_data 1` is no
>> >> longer effective.  Just remove it.
>> >>
>> >> Remove the test "Run protected-func-1 without PIE" since -fno-pic
>> >> address taken operation in the executable doesn't work with protected
>> >> symbol in a shared object by default.  Similarly, remove
>> >> protected-data-1a and protected-data-1b.  protected-data-1b can be made
>> >> working by removing HAVE_LD_PIE_COPYRELOC from GCC
>> >> (https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
>> >> ---
>> >>  bfd/elf32-i386.c                      |  1 -
>> >>  bfd/elf64-x86-64.c                    |  1 -
>> >>  bfd/elfxx-x86.c                       |  2 +-
>> >>  ld/testsuite/ld-i386/protected1.d     |  4 +++-
>> >>  ld/testsuite/ld-i386/protected3.d     |  2 +-
>> >>  ld/testsuite/ld-i386/protected6a.d    |  4 +++-
>> >>  ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
>> >>  ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
>> >>  ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
>> >>  ld/testsuite/ld-x86-64/protected3.d   |  2 +-
>> >>  ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
>> >>  ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
>> >>  ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
>> >>  13 files changed, 24 insertions(+), 39 deletions(-)
>> >>
>> >> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
>> >> index e4106d9fd3b..c3c46795731 100644
>> >> --- a/bfd/elf32-i386.c
>> >> +++ b/bfd/elf32-i386.c
>> >> @@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
>> >>  #define elf_backend_got_header_size    12
>> >>  #define elf_backend_plt_alignment      4
>> >>  #define elf_backend_dtrel_excludes_plt 1
>> >> -#define elf_backend_extern_protected_data 1
>> >>  #define elf_backend_caches_rawsize     1
>> >>  #define elf_backend_want_dynrelro      1
>> >>
>> >> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
>> >> index 6154a70bdd7..aaa5f1496b9 100644
>> >> --- a/bfd/elf64-x86-64.c
>> >> +++ b/bfd/elf64-x86-64.c
>> >> @@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
>> >>  #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
>> >>  #define elf_backend_rela_normal                    1
>> >>  #define elf_backend_plt_alignment          4
>> >> -#define elf_backend_extern_protected_data   1
>> >>  #define elf_backend_caches_rawsize         1
>> >>  #define elf_backend_dtrel_excludes_plt     1
>> >>  #define elf_backend_want_dynrelro          1
>> >> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
>> >> index acb2cc8528d..18f3d335458 100644
>> >> --- a/bfd/elfxx-x86.c
>> >> +++ b/bfd/elfxx-x86.c
>> >> @@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
>> >>       2. When building executable, there is no dynamic linker.  Or
>> >>       3. or "-z nodynamic-undefined-weak" is used.
>> >>     */
>> >> -  if (SYMBOL_REFERENCES_LOCAL (info, h)
>> >> +  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
>> >>        || (h->root.type == bfd_link_hash_undefweak
>> >>           && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
>> >>               || (bfd_link_executable (info)
>> >> diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
>> >> index a3cb5cef140..531645b8fe8 100644
>> >> --- a/ld/testsuite/ld-i386/protected1.d
>> >> +++ b/ld/testsuite/ld-i386/protected1.d
>> >> @@ -1,3 +1,5 @@
>> >>  #as: --32
>> >>  #ld: -shared -melf_i386
>> >> -#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
>> >> +#readelf: -rW
>> >> +#...
>> >> +There are no relocations in this file.
>> >> diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
>> >> index c3a6888d900..77367c4738f 100644
>> >> --- a/ld/testsuite/ld-i386/protected3.d
>> >> +++ b/ld/testsuite/ld-i386/protected3.d
>> >> @@ -8,7 +8,7 @@
>> >>  Disassembly of section .text:
>> >>
>> >>  0+[a-f0-9]+ <bar>:
>> >> -[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
>> >> +[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
>> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
>> >>  [      ]*[a-f0-9]+:    c3                      ret
>> >>  #pass
>> >> diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
>> >> index 7dc350432f4..4d3873239f9 100644
>> >> --- a/ld/testsuite/ld-i386/protected6a.d
>> >> +++ b/ld/testsuite/ld-i386/protected6a.d
>> >> @@ -1,4 +1,6 @@
>> >>  #source: protected6.s
>> >>  #as: --32
>> >>  #ld: -shared -melf_i386
>> >> -#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
>> >> +#readelf: -rW
>> >> +#...
>> >> +There are no relocations in this file.
>> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> index 130611ddf49..1f49b655f7d 100644
>> >> --- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> +++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> @@ -1,4 +1,6 @@
>> >>  #source: pr24151a.s
>> >>  #as: --x32
>> >>  #ld: -shared -melf32_x86_64
>> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> +#readelf: -rW
>> >> +#...
>> >> +There are no relocations in this file.
>> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
>> >> index 783b85a1a6f..6c48e383e01 100644
>> >> --- a/ld/testsuite/ld-x86-64/pr24151a.d
>> >> +++ b/ld/testsuite/ld-x86-64/pr24151a.d
>> >> @@ -1,3 +1,5 @@
>> >>  #as: --64
>> >>  #ld: -shared -melf_x86_64
>> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> +#readelf: -rW
>> >> +#...
>> >> +There are no relocations in this file.
>> >> diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
>> >> index 783b85a1a6f..6c48e383e01 100644
>> >> --- a/ld/testsuite/ld-x86-64/protected1.d
>> >> +++ b/ld/testsuite/ld-x86-64/protected1.d
>> >> @@ -1,3 +1,5 @@
>> >>  #as: --64
>> >>  #ld: -shared -melf_x86_64
>> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> +#readelf: -rW
>> >> +#...
>> >> +There are no relocations in this file.
>> >> diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
>> >> index 57950e4d6b6..ba63991582f 100644
>> >> --- a/ld/testsuite/ld-x86-64/protected3.d
>> >> +++ b/ld/testsuite/ld-x86-64/protected3.d
>> >> @@ -8,7 +8,7 @@
>> >>  Disassembly of section .text:
>> >>
>> >>  0+[a-f0-9]+ <bar>:
>> >> -[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>> >> +[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
>> >>  [      ]*[a-f0-9]+:    c3                      ret
>> >>  #pass
>> >> diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
>> >> index 3a7963ffd2f..50d6430b577 100644
>> >> --- a/ld/testsuite/ld-x86-64/protected6a.d
>> >> +++ b/ld/testsuite/ld-x86-64/protected6a.d
>> >> @@ -1,4 +1,6 @@
>> >>  #source: protected6.s
>> >>  #as: --64
>> >>  #ld: -shared -melf_x86_64
>> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
>> >> +#readelf: -rW
>> >> +#...
>> >> +There are no relocations in this file.
>> >> diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
>> >> index 3082084a7b8..3974246a2a8 100644
>> >> --- a/ld/testsuite/ld-x86-64/protected7a.d
>> >> +++ b/ld/testsuite/ld-x86-64/protected7a.d
>> >> @@ -1,4 +1,6 @@
>> >>  #source: protected7.s
>> >>  #as: --64
>> >>  #ld: -shared -melf_x86_64
>> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
>> >> +#readelf: -rW
>> >> +#...
>> >> +There are no relocations in this file.
>> >> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
>> >> index 5e5636bcebe..a096c0b9d0f 100644
>> >> --- a/ld/testsuite/ld-x86-64/x86-64.exp
>> >> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
>> >> @@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
>> >>             "pr23997" \
>> >>             "pass.out" \
>> >>         ] \
>> >> -       [list \
>> >> -           "Run protected-func-1 without PIE" \
>> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
>> >> -           "-Wa,-mx86-used-note=yes" \
>> >> -           { protected-func-1b.c } \
>> >> -           "protected-func-1a" \
>> >> -           "pass.out" \
>> >> -           "$NOPIE_CFLAGS" \
>> >> -       ] \
>> >>         [list \
>> >>             "Run protected-func-1 with PIE" \
>> >>             "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
>> >> @@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
>> >>             "pass.out" \
>> >>             "-fPIE" \
>> >>         ] \
>> >> -       [list \
>> >> -           "Run protected-data-1a without PIE" \
>> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
>> >> -           "-Wa,-mx86-used-note=yes" \
>> >> -           { protected-data-1b.c } \
>> >> -           "protected-data-1a" \
>> >> -           "pass.out" \
>> >> -           "$NOPIE_CFLAGS" \
>> >> -       ] \
>> >> -       [list \
>> >> -           "Run protected-data-1b with PIE" \
>> >> -           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
>> >> -           "-Wa,-mx86-used-note=yes" \
>> >> -           { protected-data-1b.c } \
>> >> -           "protected-data-1b" \
>> >> -           "pass.out" \
>> >> -           "-fPIE" \
>> >> -       ] \
>> >>         [list \
>> >>             "Run protected-data-2a without PIE" \
>> >>             "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
>> >> --
>> >> 2.37
>> >>
>> >
>> >
>> >--
>> >H.J.
>
>
>
>-- 
>H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-27 17:09       ` Fangrui Song
@ 2022-06-27 17:43         ` H.J. Lu
  2022-06-27 17:53           ` Fangrui Song
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2022-06-27 17:43 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
>
> On 2022-06-27, H.J. Lu wrote:
> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
> >>
> >> On 2022-06-26, H.J. Lu wrote:
> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
> >> >>
> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
> >> >> 2 noticeable effects for -shared:
> >> >>
> >> >> * GOT-generating relocations referencing a protected data symbol no
> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
> >> >>   confusing diagnostic below.
> >> >>
> >> >>     __attribute__((visibility("protected"))) void *foo() {
> >> >>       return (void *)foo;
> >> >>     }
> >> >>
> >> >>     // gcc -fpic -shared -fuse-ld=bfd
> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >>
> >> >> The new behavior matches arm, aarch64 (commit
> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
> >> >> linkers: gold and ld.lld.
> >> >>
> >> >> Note: if some code tries to use direct access relocations to take the
> >> >> address of foo, the pointer equality will break, but the error should be
> >> >> reported on the executable link, not on the innocent shared object link.
> >> >> glibc 2.36 will give a warning at relocation resolving time.
> >> >
> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
> >> >-z  indirect-extern-access with -shared by default instead?
> >>
> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
> >> bfd/elf-properties.c:654 will create a
> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
> >> This will probably be unexpected (and check-ld will have 280+ failures).
> >
> >This is normal when the default behavior is changed.  You can pass
> >-z noindirect-extern-access to these testcases.
>
> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
> significant behavior change and may unnecessarily break user programs
> (glibc will report an error instead of a warning).

If glibc reports an error, it is a real bug with unknown consequences
when the copy in the executable is out of sync with the protected
symbol in the shared library,

> If the executable takes the address of a protected function defined in a
> shared object, it may or may not cause a pointer equality problem (the
> shared object may not take the address) and the problem (if exists) may or
> may not be a broken invariance to the program (it may not expect pointer
> equality).
>
> All of aarch64/arm/powerpc64/riscv (likely most except x86, but I
> haven't enumerated) consider a protected data symbol local in -shared
> links. x86 did so a while ago (before 2015?).  (For
> aarch64/arm/powerpc64/riscv, I wish that we never need
> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. The property will just
> waste some bytes in every shared object without carrying much
> information.)
>
> The 280+ failures in check-ld due to the default
> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS need to be considered as
> well.
>
> >> >> With this change, `#define elf_backend_extern_protected_data 1` is no
> >> >> longer effective.  Just remove it.
> >> >>
> >> >> Remove the test "Run protected-func-1 without PIE" since -fno-pic
> >> >> address taken operation in the executable doesn't work with protected
> >> >> symbol in a shared object by default.  Similarly, remove
> >> >> protected-data-1a and protected-data-1b.  protected-data-1b can be made
> >> >> working by removing HAVE_LD_PIE_COPYRELOC from GCC
> >> >> (https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
> >> >> ---
> >> >>  bfd/elf32-i386.c                      |  1 -
> >> >>  bfd/elf64-x86-64.c                    |  1 -
> >> >>  bfd/elfxx-x86.c                       |  2 +-
> >> >>  ld/testsuite/ld-i386/protected1.d     |  4 +++-
> >> >>  ld/testsuite/ld-i386/protected3.d     |  2 +-
> >> >>  ld/testsuite/ld-i386/protected6a.d    |  4 +++-
> >> >>  ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
> >> >>  ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
> >> >>  ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
> >> >>  ld/testsuite/ld-x86-64/protected3.d   |  2 +-
> >> >>  ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
> >> >>  ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
> >> >>  ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
> >> >>  13 files changed, 24 insertions(+), 39 deletions(-)
> >> >>
> >> >> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> >> >> index e4106d9fd3b..c3c46795731 100644
> >> >> --- a/bfd/elf32-i386.c
> >> >> +++ b/bfd/elf32-i386.c
> >> >> @@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
> >> >>  #define elf_backend_got_header_size    12
> >> >>  #define elf_backend_plt_alignment      4
> >> >>  #define elf_backend_dtrel_excludes_plt 1
> >> >> -#define elf_backend_extern_protected_data 1
> >> >>  #define elf_backend_caches_rawsize     1
> >> >>  #define elf_backend_want_dynrelro      1
> >> >>
> >> >> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> >> >> index 6154a70bdd7..aaa5f1496b9 100644
> >> >> --- a/bfd/elf64-x86-64.c
> >> >> +++ b/bfd/elf64-x86-64.c
> >> >> @@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
> >> >>  #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
> >> >>  #define elf_backend_rela_normal                    1
> >> >>  #define elf_backend_plt_alignment          4
> >> >> -#define elf_backend_extern_protected_data   1
> >> >>  #define elf_backend_caches_rawsize         1
> >> >>  #define elf_backend_dtrel_excludes_plt     1
> >> >>  #define elf_backend_want_dynrelro          1
> >> >> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
> >> >> index acb2cc8528d..18f3d335458 100644
> >> >> --- a/bfd/elfxx-x86.c
> >> >> +++ b/bfd/elfxx-x86.c
> >> >> @@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
> >> >>       2. When building executable, there is no dynamic linker.  Or
> >> >>       3. or "-z nodynamic-undefined-weak" is used.
> >> >>     */
> >> >> -  if (SYMBOL_REFERENCES_LOCAL (info, h)
> >> >> +  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
> >> >>        || (h->root.type == bfd_link_hash_undefweak
> >> >>           && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
> >> >>               || (bfd_link_executable (info)
> >> >> diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
> >> >> index a3cb5cef140..531645b8fe8 100644
> >> >> --- a/ld/testsuite/ld-i386/protected1.d
> >> >> +++ b/ld/testsuite/ld-i386/protected1.d
> >> >> @@ -1,3 +1,5 @@
> >> >>  #as: --32
> >> >>  #ld: -shared -melf_i386
> >> >> -#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
> >> >> +#readelf: -rW
> >> >> +#...
> >> >> +There are no relocations in this file.
> >> >> diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
> >> >> index c3a6888d900..77367c4738f 100644
> >> >> --- a/ld/testsuite/ld-i386/protected3.d
> >> >> +++ b/ld/testsuite/ld-i386/protected3.d
> >> >> @@ -8,7 +8,7 @@
> >> >>  Disassembly of section .text:
> >> >>
> >> >>  0+[a-f0-9]+ <bar>:
> >> >> -[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
> >> >> +[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
> >> >>  [      ]*[a-f0-9]+:    c3                      ret
> >> >>  #pass
> >> >> diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
> >> >> index 7dc350432f4..4d3873239f9 100644
> >> >> --- a/ld/testsuite/ld-i386/protected6a.d
> >> >> +++ b/ld/testsuite/ld-i386/protected6a.d
> >> >> @@ -1,4 +1,6 @@
> >> >>  #source: protected6.s
> >> >>  #as: --32
> >> >>  #ld: -shared -melf_i386
> >> >> -#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
> >> >> +#readelf: -rW
> >> >> +#...
> >> >> +There are no relocations in this file.
> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> index 130611ddf49..1f49b655f7d 100644
> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> @@ -1,4 +1,6 @@
> >> >>  #source: pr24151a.s
> >> >>  #as: --x32
> >> >>  #ld: -shared -melf32_x86_64
> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> +#readelf: -rW
> >> >> +#...
> >> >> +There are no relocations in this file.
> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> index 783b85a1a6f..6c48e383e01 100644
> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> @@ -1,3 +1,5 @@
> >> >>  #as: --64
> >> >>  #ld: -shared -melf_x86_64
> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> +#readelf: -rW
> >> >> +#...
> >> >> +There are no relocations in this file.
> >> >> diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
> >> >> index 783b85a1a6f..6c48e383e01 100644
> >> >> --- a/ld/testsuite/ld-x86-64/protected1.d
> >> >> +++ b/ld/testsuite/ld-x86-64/protected1.d
> >> >> @@ -1,3 +1,5 @@
> >> >>  #as: --64
> >> >>  #ld: -shared -melf_x86_64
> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> +#readelf: -rW
> >> >> +#...
> >> >> +There are no relocations in this file.
> >> >> diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
> >> >> index 57950e4d6b6..ba63991582f 100644
> >> >> --- a/ld/testsuite/ld-x86-64/protected3.d
> >> >> +++ b/ld/testsuite/ld-x86-64/protected3.d
> >> >> @@ -8,7 +8,7 @@
> >> >>  Disassembly of section .text:
> >> >>
> >> >>  0+[a-f0-9]+ <bar>:
> >> >> -[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> >> >> +[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
> >> >>  [      ]*[a-f0-9]+:    c3                      ret
> >> >>  #pass
> >> >> diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
> >> >> index 3a7963ffd2f..50d6430b577 100644
> >> >> --- a/ld/testsuite/ld-x86-64/protected6a.d
> >> >> +++ b/ld/testsuite/ld-x86-64/protected6a.d
> >> >> @@ -1,4 +1,6 @@
> >> >>  #source: protected6.s
> >> >>  #as: --64
> >> >>  #ld: -shared -melf_x86_64
> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
> >> >> +#readelf: -rW
> >> >> +#...
> >> >> +There are no relocations in this file.
> >> >> diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
> >> >> index 3082084a7b8..3974246a2a8 100644
> >> >> --- a/ld/testsuite/ld-x86-64/protected7a.d
> >> >> +++ b/ld/testsuite/ld-x86-64/protected7a.d
> >> >> @@ -1,4 +1,6 @@
> >> >>  #source: protected7.s
> >> >>  #as: --64
> >> >>  #ld: -shared -melf_x86_64
> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
> >> >> +#readelf: -rW
> >> >> +#...
> >> >> +There are no relocations in this file.
> >> >> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> index 5e5636bcebe..a096c0b9d0f 100644
> >> >> --- a/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> @@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
> >> >>             "pr23997" \
> >> >>             "pass.out" \
> >> >>         ] \
> >> >> -       [list \
> >> >> -           "Run protected-func-1 without PIE" \
> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> -           { protected-func-1b.c } \
> >> >> -           "protected-func-1a" \
> >> >> -           "pass.out" \
> >> >> -           "$NOPIE_CFLAGS" \
> >> >> -       ] \
> >> >>         [list \
> >> >>             "Run protected-func-1 with PIE" \
> >> >>             "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
> >> >> @@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
> >> >>             "pass.out" \
> >> >>             "-fPIE" \
> >> >>         ] \
> >> >> -       [list \
> >> >> -           "Run protected-data-1a without PIE" \
> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> -           { protected-data-1b.c } \
> >> >> -           "protected-data-1a" \
> >> >> -           "pass.out" \
> >> >> -           "$NOPIE_CFLAGS" \
> >> >> -       ] \
> >> >> -       [list \
> >> >> -           "Run protected-data-1b with PIE" \
> >> >> -           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> -           { protected-data-1b.c } \
> >> >> -           "protected-data-1b" \
> >> >> -           "pass.out" \
> >> >> -           "-fPIE" \
> >> >> -       ] \
> >> >>         [list \
> >> >>             "Run protected-data-2a without PIE" \
> >> >>             "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
> >> >> --
> >> >> 2.37
> >> >>
> >> >
> >> >
> >> >--
> >> >H.J.
> >
> >
> >
> >--
> >H.J.



-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-27 17:43         ` H.J. Lu
@ 2022-06-27 17:53           ` Fangrui Song
  2022-06-27 18:26             ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Fangrui Song @ 2022-06-27 17:53 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On 2022-06-27, H.J. Lu wrote:
>On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
>>
>> On 2022-06-27, H.J. Lu wrote:
>> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
>> >>
>> >> On 2022-06-26, H.J. Lu wrote:
>> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
>> >> >>
>> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
>> >> >> 2 noticeable effects for -shared:
>> >> >>
>> >> >> * GOT-generating relocations referencing a protected data symbol no
>> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
>> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
>> >> >>   confusing diagnostic below.
>> >> >>
>> >> >>     __attribute__((visibility("protected"))) void *foo() {
>> >> >>       return (void *)foo;
>> >> >>     }
>> >> >>
>> >> >>     // gcc -fpic -shared -fuse-ld=bfd
>> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >>
>> >> >> The new behavior matches arm, aarch64 (commit
>> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
>> >> >> linkers: gold and ld.lld.
>> >> >>
>> >> >> Note: if some code tries to use direct access relocations to take the
>> >> >> address of foo, the pointer equality will break, but the error should be
>> >> >> reported on the executable link, not on the innocent shared object link.
>> >> >> glibc 2.36 will give a warning at relocation resolving time.
>> >> >
>> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
>> >> >-z  indirect-extern-access with -shared by default instead?
>> >>
>> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
>> >> bfd/elf-properties.c:654 will create a
>> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
>> >> This will probably be unexpected (and check-ld will have 280+ failures).
>> >
>> >This is normal when the default behavior is changed.  You can pass
>> >-z noindirect-extern-access to these testcases.
>>
>> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
>> significant behavior change and may unnecessarily break user programs
>> (glibc will report an error instead of a warning).
>
>If glibc reports an error, it is a real bug with unknown consequences
>when the copy in the executable is out of sync with the protected
>symbol in the shared library,

Not necessary.

In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
1 (copy relocations) and 2 (non-zero value of an undefined function
symbol) on
https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html

2 does not necessarily cause a problem. In many cases it doesn't as
function pointer equality is not an invariant a program relies upon
(at least, for many functions, the property is not used). My previous
comment has mentioned two cases.

1 likely causes a problem, but technically the shared object can define
a protected data symbol without accessing it.

>> If the executable takes the address of a protected function defined in a
>> shared object, it may or may not cause a pointer equality problem (the
>> shared object may not take the address) and the problem (if exists) may or
>> may not be a broken invariance to the program (it may not expect pointer
>> equality).
>>
>> All of aarch64/arm/powerpc64/riscv (likely most except x86, but I
>> haven't enumerated) consider a protected data symbol local in -shared
>> links. x86 did so a while ago (before 2015?).  (For
>> aarch64/arm/powerpc64/riscv, I wish that we never need
>> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. The property will just
>> waste some bytes in every shared object without carrying much
>> information.)
>>
>> The 280+ failures in check-ld due to the default
>> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS need to be considered as
>> well.
>>
>> >> >> With this change, `#define elf_backend_extern_protected_data 1` is no
>> >> >> longer effective.  Just remove it.
>> >> >>
>> >> >> Remove the test "Run protected-func-1 without PIE" since -fno-pic
>> >> >> address taken operation in the executable doesn't work with protected
>> >> >> symbol in a shared object by default.  Similarly, remove
>> >> >> protected-data-1a and protected-data-1b.  protected-data-1b can be made
>> >> >> working by removing HAVE_LD_PIE_COPYRELOC from GCC
>> >> >> (https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
>> >> >> ---
>> >> >>  bfd/elf32-i386.c                      |  1 -
>> >> >>  bfd/elf64-x86-64.c                    |  1 -
>> >> >>  bfd/elfxx-x86.c                       |  2 +-
>> >> >>  ld/testsuite/ld-i386/protected1.d     |  4 +++-
>> >> >>  ld/testsuite/ld-i386/protected3.d     |  2 +-
>> >> >>  ld/testsuite/ld-i386/protected6a.d    |  4 +++-
>> >> >>  ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
>> >> >>  ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
>> >> >>  ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
>> >> >>  ld/testsuite/ld-x86-64/protected3.d   |  2 +-
>> >> >>  ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
>> >> >>  ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
>> >> >>  ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
>> >> >>  13 files changed, 24 insertions(+), 39 deletions(-)
>> >> >>
>> >> >> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
>> >> >> index e4106d9fd3b..c3c46795731 100644
>> >> >> --- a/bfd/elf32-i386.c
>> >> >> +++ b/bfd/elf32-i386.c
>> >> >> @@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
>> >> >>  #define elf_backend_got_header_size    12
>> >> >>  #define elf_backend_plt_alignment      4
>> >> >>  #define elf_backend_dtrel_excludes_plt 1
>> >> >> -#define elf_backend_extern_protected_data 1
>> >> >>  #define elf_backend_caches_rawsize     1
>> >> >>  #define elf_backend_want_dynrelro      1
>> >> >>
>> >> >> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
>> >> >> index 6154a70bdd7..aaa5f1496b9 100644
>> >> >> --- a/bfd/elf64-x86-64.c
>> >> >> +++ b/bfd/elf64-x86-64.c
>> >> >> @@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
>> >> >>  #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
>> >> >>  #define elf_backend_rela_normal                    1
>> >> >>  #define elf_backend_plt_alignment          4
>> >> >> -#define elf_backend_extern_protected_data   1
>> >> >>  #define elf_backend_caches_rawsize         1
>> >> >>  #define elf_backend_dtrel_excludes_plt     1
>> >> >>  #define elf_backend_want_dynrelro          1
>> >> >> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
>> >> >> index acb2cc8528d..18f3d335458 100644
>> >> >> --- a/bfd/elfxx-x86.c
>> >> >> +++ b/bfd/elfxx-x86.c
>> >> >> @@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
>> >> >>       2. When building executable, there is no dynamic linker.  Or
>> >> >>       3. or "-z nodynamic-undefined-weak" is used.
>> >> >>     */
>> >> >> -  if (SYMBOL_REFERENCES_LOCAL (info, h)
>> >> >> +  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
>> >> >>        || (h->root.type == bfd_link_hash_undefweak
>> >> >>           && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
>> >> >>               || (bfd_link_executable (info)
>> >> >> diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
>> >> >> index a3cb5cef140..531645b8fe8 100644
>> >> >> --- a/ld/testsuite/ld-i386/protected1.d
>> >> >> +++ b/ld/testsuite/ld-i386/protected1.d
>> >> >> @@ -1,3 +1,5 @@
>> >> >>  #as: --32
>> >> >>  #ld: -shared -melf_i386
>> >> >> -#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
>> >> >> +#readelf: -rW
>> >> >> +#...
>> >> >> +There are no relocations in this file.
>> >> >> diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
>> >> >> index c3a6888d900..77367c4738f 100644
>> >> >> --- a/ld/testsuite/ld-i386/protected3.d
>> >> >> +++ b/ld/testsuite/ld-i386/protected3.d
>> >> >> @@ -8,7 +8,7 @@
>> >> >>  Disassembly of section .text:
>> >> >>
>> >> >>  0+[a-f0-9]+ <bar>:
>> >> >> -[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
>> >> >> +[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
>> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
>> >> >>  [      ]*[a-f0-9]+:    c3                      ret
>> >> >>  #pass
>> >> >> diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
>> >> >> index 7dc350432f4..4d3873239f9 100644
>> >> >> --- a/ld/testsuite/ld-i386/protected6a.d
>> >> >> +++ b/ld/testsuite/ld-i386/protected6a.d
>> >> >> @@ -1,4 +1,6 @@
>> >> >>  #source: protected6.s
>> >> >>  #as: --32
>> >> >>  #ld: -shared -melf_i386
>> >> >> -#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
>> >> >> +#readelf: -rW
>> >> >> +#...
>> >> >> +There are no relocations in this file.
>> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> index 130611ddf49..1f49b655f7d 100644
>> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> @@ -1,4 +1,6 @@
>> >> >>  #source: pr24151a.s
>> >> >>  #as: --x32
>> >> >>  #ld: -shared -melf32_x86_64
>> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> +#readelf: -rW
>> >> >> +#...
>> >> >> +There are no relocations in this file.
>> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> index 783b85a1a6f..6c48e383e01 100644
>> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> @@ -1,3 +1,5 @@
>> >> >>  #as: --64
>> >> >>  #ld: -shared -melf_x86_64
>> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> +#readelf: -rW
>> >> >> +#...
>> >> >> +There are no relocations in this file.
>> >> >> diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
>> >> >> index 783b85a1a6f..6c48e383e01 100644
>> >> >> --- a/ld/testsuite/ld-x86-64/protected1.d
>> >> >> +++ b/ld/testsuite/ld-x86-64/protected1.d
>> >> >> @@ -1,3 +1,5 @@
>> >> >>  #as: --64
>> >> >>  #ld: -shared -melf_x86_64
>> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> +#readelf: -rW
>> >> >> +#...
>> >> >> +There are no relocations in this file.
>> >> >> diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
>> >> >> index 57950e4d6b6..ba63991582f 100644
>> >> >> --- a/ld/testsuite/ld-x86-64/protected3.d
>> >> >> +++ b/ld/testsuite/ld-x86-64/protected3.d
>> >> >> @@ -8,7 +8,7 @@
>> >> >>  Disassembly of section .text:
>> >> >>
>> >> >>  0+[a-f0-9]+ <bar>:
>> >> >> -[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>> >> >> +[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
>> >> >>  [      ]*[a-f0-9]+:    c3                      ret
>> >> >>  #pass
>> >> >> diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> index 3a7963ffd2f..50d6430b577 100644
>> >> >> --- a/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> +++ b/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> @@ -1,4 +1,6 @@
>> >> >>  #source: protected6.s
>> >> >>  #as: --64
>> >> >>  #ld: -shared -melf_x86_64
>> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
>> >> >> +#readelf: -rW
>> >> >> +#...
>> >> >> +There are no relocations in this file.
>> >> >> diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> index 3082084a7b8..3974246a2a8 100644
>> >> >> --- a/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> +++ b/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> @@ -1,4 +1,6 @@
>> >> >>  #source: protected7.s
>> >> >>  #as: --64
>> >> >>  #ld: -shared -melf_x86_64
>> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
>> >> >> +#readelf: -rW
>> >> >> +#...
>> >> >> +There are no relocations in this file.
>> >> >> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> index 5e5636bcebe..a096c0b9d0f 100644
>> >> >> --- a/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> @@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
>> >> >>             "pr23997" \
>> >> >>             "pass.out" \
>> >> >>         ] \
>> >> >> -       [list \
>> >> >> -           "Run protected-func-1 without PIE" \
>> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
>> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> -           { protected-func-1b.c } \
>> >> >> -           "protected-func-1a" \
>> >> >> -           "pass.out" \
>> >> >> -           "$NOPIE_CFLAGS" \
>> >> >> -       ] \
>> >> >>         [list \
>> >> >>             "Run protected-func-1 with PIE" \
>> >> >>             "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
>> >> >> @@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
>> >> >>             "pass.out" \
>> >> >>             "-fPIE" \
>> >> >>         ] \
>> >> >> -       [list \
>> >> >> -           "Run protected-data-1a without PIE" \
>> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
>> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> -           { protected-data-1b.c } \
>> >> >> -           "protected-data-1a" \
>> >> >> -           "pass.out" \
>> >> >> -           "$NOPIE_CFLAGS" \
>> >> >> -       ] \
>> >> >> -       [list \
>> >> >> -           "Run protected-data-1b with PIE" \
>> >> >> -           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
>> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> -           { protected-data-1b.c } \
>> >> >> -           "protected-data-1b" \
>> >> >> -           "pass.out" \
>> >> >> -           "-fPIE" \
>> >> >> -       ] \
>> >> >>         [list \
>> >> >>             "Run protected-data-2a without PIE" \
>> >> >>             "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
>> >> >> --
>> >> >> 2.37
>> >> >>
>> >> >
>> >> >
>> >> >--
>> >> >H.J.
>> >
>> >
>> >
>> >--
>> >H.J.
>
>
>
>-- 
>H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-27 17:53           ` Fangrui Song
@ 2022-06-27 18:26             ` H.J. Lu
  2022-06-27 18:46               ` Fangrui Song
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2022-06-27 18:26 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

On Mon, Jun 27, 2022 at 10:53 AM Fangrui Song <i@maskray.me> wrote:
>
> On 2022-06-27, H.J. Lu wrote:
> >On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
> >>
> >> On 2022-06-27, H.J. Lu wrote:
> >> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
> >> >>
> >> >> On 2022-06-26, H.J. Lu wrote:
> >> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
> >> >> >>
> >> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
> >> >> >> 2 noticeable effects for -shared:
> >> >> >>
> >> >> >> * GOT-generating relocations referencing a protected data symbol no
> >> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
> >> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
> >> >> >>   confusing diagnostic below.
> >> >> >>
> >> >> >>     __attribute__((visibility("protected"))) void *foo() {
> >> >> >>       return (void *)foo;
> >> >> >>     }
> >> >> >>
> >> >> >>     // gcc -fpic -shared -fuse-ld=bfd
> >> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >>
> >> >> >> The new behavior matches arm, aarch64 (commit
> >> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
> >> >> >> linkers: gold and ld.lld.
> >> >> >>
> >> >> >> Note: if some code tries to use direct access relocations to take the
> >> >> >> address of foo, the pointer equality will break, but the error should be
> >> >> >> reported on the executable link, not on the innocent shared object link.
> >> >> >> glibc 2.36 will give a warning at relocation resolving time.
> >> >> >
> >> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
> >> >> >-z  indirect-extern-access with -shared by default instead?
> >> >>
> >> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
> >> >> bfd/elf-properties.c:654 will create a
> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
> >> >> This will probably be unexpected (and check-ld will have 280+ failures).
> >> >
> >> >This is normal when the default behavior is changed.  You can pass
> >> >-z noindirect-extern-access to these testcases.
> >>
> >> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
> >> significant behavior change and may unnecessarily break user programs
> >> (glibc will report an error instead of a warning).
> >
> >If glibc reports an error, it is a real bug with unknown consequences
> >when the copy in the executable is out of sync with the protected
> >symbol in the shared library,
>
> Not necessary.
>
> In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
> 1 (copy relocations) and 2 (non-zero value of an undefined function
> symbol) on
> https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html
>
> 2 does not necessarily cause a problem. In many cases it doesn't as
> function pointer equality is not an invariant a program relies upon
> (at least, for many functions, the property is not used). My previous
> comment has mentioned two cases.
>
> 1 likely causes a problem, but technically the shared object can define
> a protected data symbol without accessing it..

These are unknown consequences.   We don't know what the worst
cases are.

> >> If the executable takes the address of a protected function defined in a
> >> shared object, it may or may not cause a pointer equality problem (the
> >> shared object may not take the address) and the problem (if exists) may or
> >> may not be a broken invariance to the program (it may not expect pointer
> >> equality).
> >>
> >> All of aarch64/arm/powerpc64/riscv (likely most except x86, but I
> >> haven't enumerated) consider a protected data symbol local in -shared
> >> links. x86 did so a while ago (before 2015?).  (For
> >> aarch64/arm/powerpc64/riscv, I wish that we never need
> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. The property will just
> >> waste some bytes in every shared object without carrying much
> >> information.)
> >>
> >> The 280+ failures in check-ld due to the default
> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS need to be considered as
> >> well.
> >>
> >> >> >> With this change, `#define elf_backend_extern_protected_data 1` is no
> >> >> >> longer effective.  Just remove it.
> >> >> >>
> >> >> >> Remove the test "Run protected-func-1 without PIE" since -fno-pic
> >> >> >> address taken operation in the executable doesn't work with protected
> >> >> >> symbol in a shared object by default.  Similarly, remove
> >> >> >> protected-data-1a and protected-data-1b.  protected-data-1b can be made
> >> >> >> working by removing HAVE_LD_PIE_COPYRELOC from GCC
> >> >> >> (https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
> >> >> >> ---
> >> >> >>  bfd/elf32-i386.c                      |  1 -
> >> >> >>  bfd/elf64-x86-64.c                    |  1 -
> >> >> >>  bfd/elfxx-x86.c                       |  2 +-
> >> >> >>  ld/testsuite/ld-i386/protected1.d     |  4 +++-
> >> >> >>  ld/testsuite/ld-i386/protected3.d     |  2 +-
> >> >> >>  ld/testsuite/ld-i386/protected6a.d    |  4 +++-
> >> >> >>  ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
> >> >> >>  ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
> >> >> >>  ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
> >> >> >>  ld/testsuite/ld-x86-64/protected3.d   |  2 +-
> >> >> >>  ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
> >> >> >>  ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
> >> >> >>  ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
> >> >> >>  13 files changed, 24 insertions(+), 39 deletions(-)
> >> >> >>
> >> >> >> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> >> >> >> index e4106d9fd3b..c3c46795731 100644
> >> >> >> --- a/bfd/elf32-i386.c
> >> >> >> +++ b/bfd/elf32-i386.c
> >> >> >> @@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
> >> >> >>  #define elf_backend_got_header_size    12
> >> >> >>  #define elf_backend_plt_alignment      4
> >> >> >>  #define elf_backend_dtrel_excludes_plt 1
> >> >> >> -#define elf_backend_extern_protected_data 1
> >> >> >>  #define elf_backend_caches_rawsize     1
> >> >> >>  #define elf_backend_want_dynrelro      1
> >> >> >>
> >> >> >> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> >> >> >> index 6154a70bdd7..aaa5f1496b9 100644
> >> >> >> --- a/bfd/elf64-x86-64.c
> >> >> >> +++ b/bfd/elf64-x86-64.c
> >> >> >> @@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
> >> >> >>  #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
> >> >> >>  #define elf_backend_rela_normal                    1
> >> >> >>  #define elf_backend_plt_alignment          4
> >> >> >> -#define elf_backend_extern_protected_data   1
> >> >> >>  #define elf_backend_caches_rawsize         1
> >> >> >>  #define elf_backend_dtrel_excludes_plt     1
> >> >> >>  #define elf_backend_want_dynrelro          1
> >> >> >> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
> >> >> >> index acb2cc8528d..18f3d335458 100644
> >> >> >> --- a/bfd/elfxx-x86.c
> >> >> >> +++ b/bfd/elfxx-x86.c
> >> >> >> @@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
> >> >> >>       2. When building executable, there is no dynamic linker.  Or
> >> >> >>       3. or "-z nodynamic-undefined-weak" is used.
> >> >> >>     */
> >> >> >> -  if (SYMBOL_REFERENCES_LOCAL (info, h)
> >> >> >> +  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
> >> >> >>        || (h->root.type == bfd_link_hash_undefweak
> >> >> >>           && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
> >> >> >>               || (bfd_link_executable (info)
> >> >> >> diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
> >> >> >> index a3cb5cef140..531645b8fe8 100644
> >> >> >> --- a/ld/testsuite/ld-i386/protected1.d
> >> >> >> +++ b/ld/testsuite/ld-i386/protected1.d
> >> >> >> @@ -1,3 +1,5 @@
> >> >> >>  #as: --32
> >> >> >>  #ld: -shared -melf_i386
> >> >> >> -#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
> >> >> >> +#readelf: -rW
> >> >> >> +#...
> >> >> >> +There are no relocations in this file.
> >> >> >> diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
> >> >> >> index c3a6888d900..77367c4738f 100644
> >> >> >> --- a/ld/testsuite/ld-i386/protected3.d
> >> >> >> +++ b/ld/testsuite/ld-i386/protected3.d
> >> >> >> @@ -8,7 +8,7 @@
> >> >> >>  Disassembly of section .text:
> >> >> >>
> >> >> >>  0+[a-f0-9]+ <bar>:
> >> >> >> -[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
> >> >> >> +[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
> >> >> >>  #pass
> >> >> >> diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
> >> >> >> index 7dc350432f4..4d3873239f9 100644
> >> >> >> --- a/ld/testsuite/ld-i386/protected6a.d
> >> >> >> +++ b/ld/testsuite/ld-i386/protected6a.d
> >> >> >> @@ -1,4 +1,6 @@
> >> >> >>  #source: protected6.s
> >> >> >>  #as: --32
> >> >> >>  #ld: -shared -melf_i386
> >> >> >> -#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
> >> >> >> +#readelf: -rW
> >> >> >> +#...
> >> >> >> +There are no relocations in this file.
> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> >> index 130611ddf49..1f49b655f7d 100644
> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> >> @@ -1,4 +1,6 @@
> >> >> >>  #source: pr24151a.s
> >> >> >>  #as: --x32
> >> >> >>  #ld: -shared -melf32_x86_64
> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> +#readelf: -rW
> >> >> >> +#...
> >> >> >> +There are no relocations in this file.
> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> >> index 783b85a1a6f..6c48e383e01 100644
> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> >> @@ -1,3 +1,5 @@
> >> >> >>  #as: --64
> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> +#readelf: -rW
> >> >> >> +#...
> >> >> >> +There are no relocations in this file.
> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
> >> >> >> index 783b85a1a6f..6c48e383e01 100644
> >> >> >> --- a/ld/testsuite/ld-x86-64/protected1.d
> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected1.d
> >> >> >> @@ -1,3 +1,5 @@
> >> >> >>  #as: --64
> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> +#readelf: -rW
> >> >> >> +#...
> >> >> >> +There are no relocations in this file.
> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
> >> >> >> index 57950e4d6b6..ba63991582f 100644
> >> >> >> --- a/ld/testsuite/ld-x86-64/protected3.d
> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected3.d
> >> >> >> @@ -8,7 +8,7 @@
> >> >> >>  Disassembly of section .text:
> >> >> >>
> >> >> >>  0+[a-f0-9]+ <bar>:
> >> >> >> -[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> >> >> >> +[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
> >> >> >>  #pass
> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
> >> >> >> index 3a7963ffd2f..50d6430b577 100644
> >> >> >> --- a/ld/testsuite/ld-x86-64/protected6a.d
> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected6a.d
> >> >> >> @@ -1,4 +1,6 @@
> >> >> >>  #source: protected6.s
> >> >> >>  #as: --64
> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
> >> >> >> +#readelf: -rW
> >> >> >> +#...
> >> >> >> +There are no relocations in this file.
> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
> >> >> >> index 3082084a7b8..3974246a2a8 100644
> >> >> >> --- a/ld/testsuite/ld-x86-64/protected7a.d
> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected7a.d
> >> >> >> @@ -1,4 +1,6 @@
> >> >> >>  #source: protected7.s
> >> >> >>  #as: --64
> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
> >> >> >> +#readelf: -rW
> >> >> >> +#...
> >> >> >> +There are no relocations in this file.
> >> >> >> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> >> index 5e5636bcebe..a096c0b9d0f 100644
> >> >> >> --- a/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> >> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> >> @@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
> >> >> >>             "pr23997" \
> >> >> >>             "pass.out" \
> >> >> >>         ] \
> >> >> >> -       [list \
> >> >> >> -           "Run protected-func-1 without PIE" \
> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
> >> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> >> -           { protected-func-1b.c } \
> >> >> >> -           "protected-func-1a" \
> >> >> >> -           "pass.out" \
> >> >> >> -           "$NOPIE_CFLAGS" \
> >> >> >> -       ] \
> >> >> >>         [list \
> >> >> >>             "Run protected-func-1 with PIE" \
> >> >> >>             "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
> >> >> >> @@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
> >> >> >>             "pass.out" \
> >> >> >>             "-fPIE" \
> >> >> >>         ] \
> >> >> >> -       [list \
> >> >> >> -           "Run protected-data-1a without PIE" \
> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
> >> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> >> -           { protected-data-1b.c } \
> >> >> >> -           "protected-data-1a" \
> >> >> >> -           "pass.out" \
> >> >> >> -           "$NOPIE_CFLAGS" \
> >> >> >> -       ] \
> >> >> >> -       [list \
> >> >> >> -           "Run protected-data-1b with PIE" \
> >> >> >> -           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
> >> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> >> -           { protected-data-1b.c } \
> >> >> >> -           "protected-data-1b" \
> >> >> >> -           "pass.out" \
> >> >> >> -           "-fPIE" \
> >> >> >> -       ] \
> >> >> >>         [list \
> >> >> >>             "Run protected-data-2a without PIE" \
> >> >> >>             "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
> >> >> >> --
> >> >> >> 2.37
> >> >> >>
> >> >> >
> >> >> >
> >> >> >--
> >> >> >H.J.
> >> >
> >> >
> >> >
> >> >--
> >> >H.J.
> >
> >
> >
> >--
> >H.J.



-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-27 18:26             ` H.J. Lu
@ 2022-06-27 18:46               ` Fangrui Song
  2022-06-27 18:57                 ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Fangrui Song @ 2022-06-27 18:46 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On 2022-06-27, H.J. Lu wrote:
>On Mon, Jun 27, 2022 at 10:53 AM Fangrui Song <i@maskray.me> wrote:
>>
>> On 2022-06-27, H.J. Lu wrote:
>> >On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
>> >>
>> >> On 2022-06-27, H.J. Lu wrote:
>> >> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
>> >> >>
>> >> >> On 2022-06-26, H.J. Lu wrote:
>> >> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
>> >> >> >>
>> >> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
>> >> >> >> 2 noticeable effects for -shared:
>> >> >> >>
>> >> >> >> * GOT-generating relocations referencing a protected data symbol no
>> >> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
>> >> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
>> >> >> >>   confusing diagnostic below.
>> >> >> >>
>> >> >> >>     __attribute__((visibility("protected"))) void *foo() {
>> >> >> >>       return (void *)foo;
>> >> >> >>     }
>> >> >> >>
>> >> >> >>     // gcc -fpic -shared -fuse-ld=bfd
>> >> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >>
>> >> >> >> The new behavior matches arm, aarch64 (commit
>> >> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
>> >> >> >> linkers: gold and ld.lld.
>> >> >> >>
>> >> >> >> Note: if some code tries to use direct access relocations to take the
>> >> >> >> address of foo, the pointer equality will break, but the error should be
>> >> >> >> reported on the executable link, not on the innocent shared object link.
>> >> >> >> glibc 2.36 will give a warning at relocation resolving time.
>> >> >> >
>> >> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
>> >> >> >-z  indirect-extern-access with -shared by default instead?
>> >> >>
>> >> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
>> >> >> bfd/elf-properties.c:654 will create a
>> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
>> >> >> This will probably be unexpected (and check-ld will have 280+ failures).
>> >> >
>> >> >This is normal when the default behavior is changed.  You can pass
>> >> >-z noindirect-extern-access to these testcases.
>> >>
>> >> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
>> >> significant behavior change and may unnecessarily break user programs
>> >> (glibc will report an error instead of a warning).
>> >
>> >If glibc reports an error, it is a real bug with unknown consequences
>> >when the copy in the executable is out of sync with the protected
>> >symbol in the shared library,
>>
>> Not necessary.
>>
>> In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
>> 1 (copy relocations) and 2 (non-zero value of an undefined function
>> symbol) on
>> https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html
>>
>> 2 does not necessarily cause a problem. In many cases it doesn't as
>> function pointer equality is not an invariant a program relies upon
>> (at least, for many functions, the property is not used). My previous
>> comment has mentioned two cases.
>>
>> 1 likely causes a problem, but technically the shared object can define
>> a protected data symbol without accessing it..
>
>These are unknown consequences.   We don't know what the worst
>cases are.

They are, just like when a shared object is linked with -Bsymbolic.

This patch focuses on changing the x86 default to a sane value (matching
aarch64/arm/powerpc64/riscv/etc) and enabling future removal of
`extern_protected_data`.  If you want to switch to
indirect-extern-access default for x86, while I think unnecessary, I will not object.

But I'd note that we aren't really ready for the GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS default.
One major issue: -fPIE is widely used nowadays and GCC>=5 has the PIE copy relocation "regression".
(My https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html
will fix it for future GCC, but the patch seems to get stuck since 2021-05-11.)

>> >> If the executable takes the address of a protected function defined in a
>> >> shared object, it may or may not cause a pointer equality problem (the
>> >> shared object may not take the address) and the problem (if exists) may or
>> >> may not be a broken invariance to the program (it may not expect pointer
>> >> equality).
>> >>
>> >> All of aarch64/arm/powerpc64/riscv (likely most except x86, but I
>> >> haven't enumerated) consider a protected data symbol local in -shared
>> >> links. x86 did so a while ago (before 2015?).  (For
>> >> aarch64/arm/powerpc64/riscv, I wish that we never need
>> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. The property will just
>> >> waste some bytes in every shared object without carrying much
>> >> information.)
>> >>
>> >> The 280+ failures in check-ld due to the default
>> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS need to be considered as
>> >> well.
>> >>
>> >> >> >> With this change, `#define elf_backend_extern_protected_data 1` is no
>> >> >> >> longer effective.  Just remove it.
>> >> >> >>
>> >> >> >> Remove the test "Run protected-func-1 without PIE" since -fno-pic
>> >> >> >> address taken operation in the executable doesn't work with protected
>> >> >> >> symbol in a shared object by default.  Similarly, remove
>> >> >> >> protected-data-1a and protected-data-1b.  protected-data-1b can be made
>> >> >> >> working by removing HAVE_LD_PIE_COPYRELOC from GCC
>> >> >> >> (https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
>> >> >> >> ---
>> >> >> >>  bfd/elf32-i386.c                      |  1 -
>> >> >> >>  bfd/elf64-x86-64.c                    |  1 -
>> >> >> >>  bfd/elfxx-x86.c                       |  2 +-
>> >> >> >>  ld/testsuite/ld-i386/protected1.d     |  4 +++-
>> >> >> >>  ld/testsuite/ld-i386/protected3.d     |  2 +-
>> >> >> >>  ld/testsuite/ld-i386/protected6a.d    |  4 +++-
>> >> >> >>  ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
>> >> >> >>  ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
>> >> >> >>  ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
>> >> >> >>  ld/testsuite/ld-x86-64/protected3.d   |  2 +-
>> >> >> >>  ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
>> >> >> >>  ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
>> >> >> >>  ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
>> >> >> >>  13 files changed, 24 insertions(+), 39 deletions(-)
>> >> >> >>
>> >> >> >> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
>> >> >> >> index e4106d9fd3b..c3c46795731 100644
>> >> >> >> --- a/bfd/elf32-i386.c
>> >> >> >> +++ b/bfd/elf32-i386.c
>> >> >> >> @@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
>> >> >> >>  #define elf_backend_got_header_size    12
>> >> >> >>  #define elf_backend_plt_alignment      4
>> >> >> >>  #define elf_backend_dtrel_excludes_plt 1
>> >> >> >> -#define elf_backend_extern_protected_data 1
>> >> >> >>  #define elf_backend_caches_rawsize     1
>> >> >> >>  #define elf_backend_want_dynrelro      1
>> >> >> >>
>> >> >> >> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
>> >> >> >> index 6154a70bdd7..aaa5f1496b9 100644
>> >> >> >> --- a/bfd/elf64-x86-64.c
>> >> >> >> +++ b/bfd/elf64-x86-64.c
>> >> >> >> @@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
>> >> >> >>  #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
>> >> >> >>  #define elf_backend_rela_normal                    1
>> >> >> >>  #define elf_backend_plt_alignment          4
>> >> >> >> -#define elf_backend_extern_protected_data   1
>> >> >> >>  #define elf_backend_caches_rawsize         1
>> >> >> >>  #define elf_backend_dtrel_excludes_plt     1
>> >> >> >>  #define elf_backend_want_dynrelro          1
>> >> >> >> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
>> >> >> >> index acb2cc8528d..18f3d335458 100644
>> >> >> >> --- a/bfd/elfxx-x86.c
>> >> >> >> +++ b/bfd/elfxx-x86.c
>> >> >> >> @@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
>> >> >> >>       2. When building executable, there is no dynamic linker.  Or
>> >> >> >>       3. or "-z nodynamic-undefined-weak" is used.
>> >> >> >>     */
>> >> >> >> -  if (SYMBOL_REFERENCES_LOCAL (info, h)
>> >> >> >> +  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
>> >> >> >>        || (h->root.type == bfd_link_hash_undefweak
>> >> >> >>           && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
>> >> >> >>               || (bfd_link_executable (info)
>> >> >> >> diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
>> >> >> >> index a3cb5cef140..531645b8fe8 100644
>> >> >> >> --- a/ld/testsuite/ld-i386/protected1.d
>> >> >> >> +++ b/ld/testsuite/ld-i386/protected1.d
>> >> >> >> @@ -1,3 +1,5 @@
>> >> >> >>  #as: --32
>> >> >> >>  #ld: -shared -melf_i386
>> >> >> >> -#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
>> >> >> >> +#readelf: -rW
>> >> >> >> +#...
>> >> >> >> +There are no relocations in this file.
>> >> >> >> diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
>> >> >> >> index c3a6888d900..77367c4738f 100644
>> >> >> >> --- a/ld/testsuite/ld-i386/protected3.d
>> >> >> >> +++ b/ld/testsuite/ld-i386/protected3.d
>> >> >> >> @@ -8,7 +8,7 @@
>> >> >> >>  Disassembly of section .text:
>> >> >> >>
>> >> >> >>  0+[a-f0-9]+ <bar>:
>> >> >> >> -[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
>> >> >> >> +[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
>> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
>> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
>> >> >> >>  #pass
>> >> >> >> diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
>> >> >> >> index 7dc350432f4..4d3873239f9 100644
>> >> >> >> --- a/ld/testsuite/ld-i386/protected6a.d
>> >> >> >> +++ b/ld/testsuite/ld-i386/protected6a.d
>> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >>  #source: protected6.s
>> >> >> >>  #as: --32
>> >> >> >>  #ld: -shared -melf_i386
>> >> >> >> -#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
>> >> >> >> +#readelf: -rW
>> >> >> >> +#...
>> >> >> >> +There are no relocations in this file.
>> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> >> index 130611ddf49..1f49b655f7d 100644
>> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >>  #source: pr24151a.s
>> >> >> >>  #as: --x32
>> >> >> >>  #ld: -shared -melf32_x86_64
>> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> +#readelf: -rW
>> >> >> >> +#...
>> >> >> >> +There are no relocations in this file.
>> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> >> index 783b85a1a6f..6c48e383e01 100644
>> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> >> @@ -1,3 +1,5 @@
>> >> >> >>  #as: --64
>> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> +#readelf: -rW
>> >> >> >> +#...
>> >> >> >> +There are no relocations in this file.
>> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
>> >> >> >> index 783b85a1a6f..6c48e383e01 100644
>> >> >> >> --- a/ld/testsuite/ld-x86-64/protected1.d
>> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected1.d
>> >> >> >> @@ -1,3 +1,5 @@
>> >> >> >>  #as: --64
>> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> +#readelf: -rW
>> >> >> >> +#...
>> >> >> >> +There are no relocations in this file.
>> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
>> >> >> >> index 57950e4d6b6..ba63991582f 100644
>> >> >> >> --- a/ld/testsuite/ld-x86-64/protected3.d
>> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected3.d
>> >> >> >> @@ -8,7 +8,7 @@
>> >> >> >>  Disassembly of section .text:
>> >> >> >>
>> >> >> >>  0+[a-f0-9]+ <bar>:
>> >> >> >> -[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>> >> >> >> +[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
>> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
>> >> >> >>  #pass
>> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> >> index 3a7963ffd2f..50d6430b577 100644
>> >> >> >> --- a/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >>  #source: protected6.s
>> >> >> >>  #as: --64
>> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
>> >> >> >> +#readelf: -rW
>> >> >> >> +#...
>> >> >> >> +There are no relocations in this file.
>> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> >> index 3082084a7b8..3974246a2a8 100644
>> >> >> >> --- a/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >>  #source: protected7.s
>> >> >> >>  #as: --64
>> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
>> >> >> >> +#readelf: -rW
>> >> >> >> +#...
>> >> >> >> +There are no relocations in this file.
>> >> >> >> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> >> index 5e5636bcebe..a096c0b9d0f 100644
>> >> >> >> --- a/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> >> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> >> @@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
>> >> >> >>             "pr23997" \
>> >> >> >>             "pass.out" \
>> >> >> >>         ] \
>> >> >> >> -       [list \
>> >> >> >> -           "Run protected-func-1 without PIE" \
>> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
>> >> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> >> -           { protected-func-1b.c } \
>> >> >> >> -           "protected-func-1a" \
>> >> >> >> -           "pass.out" \
>> >> >> >> -           "$NOPIE_CFLAGS" \
>> >> >> >> -       ] \
>> >> >> >>         [list \
>> >> >> >>             "Run protected-func-1 with PIE" \
>> >> >> >>             "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
>> >> >> >> @@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
>> >> >> >>             "pass.out" \
>> >> >> >>             "-fPIE" \
>> >> >> >>         ] \
>> >> >> >> -       [list \
>> >> >> >> -           "Run protected-data-1a without PIE" \
>> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
>> >> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> >> -           { protected-data-1b.c } \
>> >> >> >> -           "protected-data-1a" \
>> >> >> >> -           "pass.out" \
>> >> >> >> -           "$NOPIE_CFLAGS" \
>> >> >> >> -       ] \
>> >> >> >> -       [list \
>> >> >> >> -           "Run protected-data-1b with PIE" \
>> >> >> >> -           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
>> >> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> >> -           { protected-data-1b.c } \
>> >> >> >> -           "protected-data-1b" \
>> >> >> >> -           "pass.out" \
>> >> >> >> -           "-fPIE" \
>> >> >> >> -       ] \
>> >> >> >>         [list \
>> >> >> >>             "Run protected-data-2a without PIE" \
>> >> >> >>             "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
>> >> >> >> --
>> >> >> >> 2.37
>> >> >> >>
>> >> >> >
>> >> >> >
>> >> >> >--
>> >> >> >H.J.
>> >> >
>> >> >
>> >> >
>> >> >--
>> >> >H.J.
>> >
>> >
>> >
>> >--
>> >H.J.
>
>
>
>-- 
>H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-27 18:46               ` Fangrui Song
@ 2022-06-27 18:57                 ` H.J. Lu
  2022-06-28  3:07                   ` Fangrui Song
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2022-06-27 18:57 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

On Mon, Jun 27, 2022 at 11:46 AM Fangrui Song <i@maskray.me> wrote:
>
> On 2022-06-27, H.J. Lu wrote:
> >On Mon, Jun 27, 2022 at 10:53 AM Fangrui Song <i@maskray.me> wrote:
> >>
> >> On 2022-06-27, H.J. Lu wrote:
> >> >On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
> >> >>
> >> >> On 2022-06-27, H.J. Lu wrote:
> >> >> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
> >> >> >>
> >> >> >> On 2022-06-26, H.J. Lu wrote:
> >> >> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
> >> >> >> >>
> >> >> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
> >> >> >> >> 2 noticeable effects for -shared:
> >> >> >> >>
> >> >> >> >> * GOT-generating relocations referencing a protected data symbol no
> >> >> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
> >> >> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
> >> >> >> >>   confusing diagnostic below.
> >> >> >> >>
> >> >> >> >>     __attribute__((visibility("protected"))) void *foo() {
> >> >> >> >>       return (void *)foo;
> >> >> >> >>     }
> >> >> >> >>
> >> >> >> >>     // gcc -fpic -shared -fuse-ld=bfd
> >> >> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> >>
> >> >> >> >> The new behavior matches arm, aarch64 (commit
> >> >> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
> >> >> >> >> linkers: gold and ld.lld.
> >> >> >> >>
> >> >> >> >> Note: if some code tries to use direct access relocations to take the
> >> >> >> >> address of foo, the pointer equality will break, but the error should be
> >> >> >> >> reported on the executable link, not on the innocent shared object link.
> >> >> >> >> glibc 2.36 will give a warning at relocation resolving time.
> >> >> >> >
> >> >> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
> >> >> >> >-z  indirect-extern-access with -shared by default instead?
> >> >> >>
> >> >> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
> >> >> >> bfd/elf-properties.c:654 will create a
> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
> >> >> >> This will probably be unexpected (and check-ld will have 280+ failures).
> >> >> >
> >> >> >This is normal when the default behavior is changed.  You can pass
> >> >> >-z noindirect-extern-access to these testcases.
> >> >>
> >> >> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
> >> >> significant behavior change and may unnecessarily break user programs
> >> >> (glibc will report an error instead of a warning).
> >> >
> >> >If glibc reports an error, it is a real bug with unknown consequences
> >> >when the copy in the executable is out of sync with the protected
> >> >symbol in the shared library,
> >>
> >> Not necessary.
> >>
> >> In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
> >> 1 (copy relocations) and 2 (non-zero value of an undefined function
> >> symbol) on
> >> https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html
> >>
> >> 2 does not necessarily cause a problem. In many cases it doesn't as
> >> function pointer equality is not an invariant a program relies upon
> >> (at least, for many functions, the property is not used). My previous
> >> comment has mentioned two cases.
> >>
> >> 1 likely causes a problem, but technically the shared object can define
> >> a protected data symbol without accessing it..
> >
> >These are unknown consequences.   We don't know what the worst
> >cases are.
>
> They are, just like when a shared object is linked with -Bsymbolic.

They have to deal with it since it is done on purpose.

> This patch focuses on changing the x86 default to a sane value (matching
> aarch64/arm/powerpc64/riscv/etc) and enabling future removal of
> `extern_protected_data`.  If you want to switch to
> indirect-extern-access default for x86, while I think unnecessary, I will not object.

extern_protected_data can be safely removed only when
direct access to external symbols are disallowed.   We can't
have both ways.

> But I'd note that we aren't really ready for the GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS default.
> One major issue: -fPIE is widely used nowadays and GCC>=5 has the PIE copy relocation "regression".

-fno-PIE still has copy relocation.

> (My https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html
> will fix it for future GCC, but the patch seems to get stuck since 2021-05-11.)
>
> >> >> If the executable takes the address of a protected function defined in a
> >> >> shared object, it may or may not cause a pointer equality problem (the
> >> >> shared object may not take the address) and the problem (if exists) may or
> >> >> may not be a broken invariance to the program (it may not expect pointer
> >> >> equality).
> >> >>
> >> >> All of aarch64/arm/powerpc64/riscv (likely most except x86, but I
> >> >> haven't enumerated) consider a protected data symbol local in -shared
> >> >> links. x86 did so a while ago (before 2015?).  (For
> >> >> aarch64/arm/powerpc64/riscv, I wish that we never need
> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. The property will just
> >> >> waste some bytes in every shared object without carrying much
> >> >> information.)
> >> >>
> >> >> The 280+ failures in check-ld due to the default
> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS need to be considered as
> >> >> well.
> >> >>
> >> >> >> >> With this change, `#define elf_backend_extern_protected_data 1` is no
> >> >> >> >> longer effective.  Just remove it.
> >> >> >> >>
> >> >> >> >> Remove the test "Run protected-func-1 without PIE" since -fno-pic
> >> >> >> >> address taken operation in the executable doesn't work with protected
> >> >> >> >> symbol in a shared object by default.  Similarly, remove
> >> >> >> >> protected-data-1a and protected-data-1b.  protected-data-1b can be made
> >> >> >> >> working by removing HAVE_LD_PIE_COPYRELOC from GCC
> >> >> >> >> (https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
> >> >> >> >> ---
> >> >> >> >>  bfd/elf32-i386.c                      |  1 -
> >> >> >> >>  bfd/elf64-x86-64.c                    |  1 -
> >> >> >> >>  bfd/elfxx-x86.c                       |  2 +-
> >> >> >> >>  ld/testsuite/ld-i386/protected1.d     |  4 +++-
> >> >> >> >>  ld/testsuite/ld-i386/protected3.d     |  2 +-
> >> >> >> >>  ld/testsuite/ld-i386/protected6a.d    |  4 +++-
> >> >> >> >>  ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
> >> >> >> >>  ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
> >> >> >> >>  ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
> >> >> >> >>  ld/testsuite/ld-x86-64/protected3.d   |  2 +-
> >> >> >> >>  ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
> >> >> >> >>  ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
> >> >> >> >>  ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
> >> >> >> >>  13 files changed, 24 insertions(+), 39 deletions(-)
> >> >> >> >>
> >> >> >> >> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> >> >> >> >> index e4106d9fd3b..c3c46795731 100644
> >> >> >> >> --- a/bfd/elf32-i386.c
> >> >> >> >> +++ b/bfd/elf32-i386.c
> >> >> >> >> @@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
> >> >> >> >>  #define elf_backend_got_header_size    12
> >> >> >> >>  #define elf_backend_plt_alignment      4
> >> >> >> >>  #define elf_backend_dtrel_excludes_plt 1
> >> >> >> >> -#define elf_backend_extern_protected_data 1
> >> >> >> >>  #define elf_backend_caches_rawsize     1
> >> >> >> >>  #define elf_backend_want_dynrelro      1
> >> >> >> >>
> >> >> >> >> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> >> >> >> >> index 6154a70bdd7..aaa5f1496b9 100644
> >> >> >> >> --- a/bfd/elf64-x86-64.c
> >> >> >> >> +++ b/bfd/elf64-x86-64.c
> >> >> >> >> @@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
> >> >> >> >>  #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
> >> >> >> >>  #define elf_backend_rela_normal                    1
> >> >> >> >>  #define elf_backend_plt_alignment          4
> >> >> >> >> -#define elf_backend_extern_protected_data   1
> >> >> >> >>  #define elf_backend_caches_rawsize         1
> >> >> >> >>  #define elf_backend_dtrel_excludes_plt     1
> >> >> >> >>  #define elf_backend_want_dynrelro          1
> >> >> >> >> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
> >> >> >> >> index acb2cc8528d..18f3d335458 100644
> >> >> >> >> --- a/bfd/elfxx-x86.c
> >> >> >> >> +++ b/bfd/elfxx-x86.c
> >> >> >> >> @@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
> >> >> >> >>       2. When building executable, there is no dynamic linker.  Or
> >> >> >> >>       3. or "-z nodynamic-undefined-weak" is used.
> >> >> >> >>     */
> >> >> >> >> -  if (SYMBOL_REFERENCES_LOCAL (info, h)
> >> >> >> >> +  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
> >> >> >> >>        || (h->root.type == bfd_link_hash_undefweak
> >> >> >> >>           && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
> >> >> >> >>               || (bfd_link_executable (info)
> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
> >> >> >> >> index a3cb5cef140..531645b8fe8 100644
> >> >> >> >> --- a/ld/testsuite/ld-i386/protected1.d
> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected1.d
> >> >> >> >> @@ -1,3 +1,5 @@
> >> >> >> >>  #as: --32
> >> >> >> >>  #ld: -shared -melf_i386
> >> >> >> >> -#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
> >> >> >> >> +#readelf: -rW
> >> >> >> >> +#...
> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
> >> >> >> >> index c3a6888d900..77367c4738f 100644
> >> >> >> >> --- a/ld/testsuite/ld-i386/protected3.d
> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected3.d
> >> >> >> >> @@ -8,7 +8,7 @@
> >> >> >> >>  Disassembly of section .text:
> >> >> >> >>
> >> >> >> >>  0+[a-f0-9]+ <bar>:
> >> >> >> >> -[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
> >> >> >> >> +[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
> >> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
> >> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
> >> >> >> >>  #pass
> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
> >> >> >> >> index 7dc350432f4..4d3873239f9 100644
> >> >> >> >> --- a/ld/testsuite/ld-i386/protected6a.d
> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected6a.d
> >> >> >> >> @@ -1,4 +1,6 @@
> >> >> >> >>  #source: protected6.s
> >> >> >> >>  #as: --32
> >> >> >> >>  #ld: -shared -melf_i386
> >> >> >> >> -#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
> >> >> >> >> +#readelf: -rW
> >> >> >> >> +#...
> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> >> >> index 130611ddf49..1f49b655f7d 100644
> >> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> >> >> @@ -1,4 +1,6 @@
> >> >> >> >>  #source: pr24151a.s
> >> >> >> >>  #as: --x32
> >> >> >> >>  #ld: -shared -melf32_x86_64
> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> >> +#readelf: -rW
> >> >> >> >> +#...
> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> >> >> index 783b85a1a6f..6c48e383e01 100644
> >> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> >> >> @@ -1,3 +1,5 @@
> >> >> >> >>  #as: --64
> >> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> >> +#readelf: -rW
> >> >> >> >> +#...
> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
> >> >> >> >> index 783b85a1a6f..6c48e383e01 100644
> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected1.d
> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected1.d
> >> >> >> >> @@ -1,3 +1,5 @@
> >> >> >> >>  #as: --64
> >> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> >> +#readelf: -rW
> >> >> >> >> +#...
> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
> >> >> >> >> index 57950e4d6b6..ba63991582f 100644
> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected3.d
> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected3.d
> >> >> >> >> @@ -8,7 +8,7 @@
> >> >> >> >>  Disassembly of section .text:
> >> >> >> >>
> >> >> >> >>  0+[a-f0-9]+ <bar>:
> >> >> >> >> -[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> >> >> >> >> +[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> >> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
> >> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
> >> >> >> >>  #pass
> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
> >> >> >> >> index 3a7963ffd2f..50d6430b577 100644
> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected6a.d
> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected6a.d
> >> >> >> >> @@ -1,4 +1,6 @@
> >> >> >> >>  #source: protected6.s
> >> >> >> >>  #as: --64
> >> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
> >> >> >> >> +#readelf: -rW
> >> >> >> >> +#...
> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
> >> >> >> >> index 3082084a7b8..3974246a2a8 100644
> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected7a.d
> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected7a.d
> >> >> >> >> @@ -1,4 +1,6 @@
> >> >> >> >>  #source: protected7.s
> >> >> >> >>  #as: --64
> >> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
> >> >> >> >> +#readelf: -rW
> >> >> >> >> +#...
> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> >> >> index 5e5636bcebe..a096c0b9d0f 100644
> >> >> >> >> --- a/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> >> >> @@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
> >> >> >> >>             "pr23997" \
> >> >> >> >>             "pass.out" \
> >> >> >> >>         ] \
> >> >> >> >> -       [list \
> >> >> >> >> -           "Run protected-func-1 without PIE" \
> >> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> >> >> -           { protected-func-1b.c } \
> >> >> >> >> -           "protected-func-1a" \
> >> >> >> >> -           "pass.out" \
> >> >> >> >> -           "$NOPIE_CFLAGS" \
> >> >> >> >> -       ] \
> >> >> >> >>         [list \
> >> >> >> >>             "Run protected-func-1 with PIE" \
> >> >> >> >>             "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
> >> >> >> >> @@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
> >> >> >> >>             "pass.out" \
> >> >> >> >>             "-fPIE" \
> >> >> >> >>         ] \
> >> >> >> >> -       [list \
> >> >> >> >> -           "Run protected-data-1a without PIE" \
> >> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> >> >> -           { protected-data-1b.c } \
> >> >> >> >> -           "protected-data-1a" \
> >> >> >> >> -           "pass.out" \
> >> >> >> >> -           "$NOPIE_CFLAGS" \
> >> >> >> >> -       ] \
> >> >> >> >> -       [list \
> >> >> >> >> -           "Run protected-data-1b with PIE" \
> >> >> >> >> -           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> >> >> -           { protected-data-1b.c } \
> >> >> >> >> -           "protected-data-1b" \
> >> >> >> >> -           "pass.out" \
> >> >> >> >> -           "-fPIE" \
> >> >> >> >> -       ] \
> >> >> >> >>         [list \
> >> >> >> >>             "Run protected-data-2a without PIE" \
> >> >> >> >>             "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
> >> >> >> >> --
> >> >> >> >> 2.37
> >> >> >> >>
> >> >> >> >
> >> >> >> >
> >> >> >> >--
> >> >> >> >H.J.
> >> >> >
> >> >> >
> >> >> >
> >> >> >--
> >> >> >H.J.
> >> >
> >> >
> >> >
> >> >--
> >> >H.J.
> >
> >
> >
> >--
> >H.J.



-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-27 18:57                 ` H.J. Lu
@ 2022-06-28  3:07                   ` Fangrui Song
  2022-06-28  3:24                     ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Fangrui Song @ 2022-06-28  3:07 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On 2022-06-27, H.J. Lu wrote:
>On Mon, Jun 27, 2022 at 11:46 AM Fangrui Song <i@maskray.me> wrote:
>>
>> On 2022-06-27, H.J. Lu wrote:
>> >On Mon, Jun 27, 2022 at 10:53 AM Fangrui Song <i@maskray.me> wrote:
>> >>
>> >> On 2022-06-27, H.J. Lu wrote:
>> >> >On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
>> >> >>
>> >> >> On 2022-06-27, H.J. Lu wrote:
>> >> >> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
>> >> >> >>
>> >> >> >> On 2022-06-26, H.J. Lu wrote:
>> >> >> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
>> >> >> >> >>
>> >> >> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
>> >> >> >> >> 2 noticeable effects for -shared:
>> >> >> >> >>
>> >> >> >> >> * GOT-generating relocations referencing a protected data symbol no
>> >> >> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
>> >> >> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
>> >> >> >> >>   confusing diagnostic below.
>> >> >> >> >>
>> >> >> >> >>     __attribute__((visibility("protected"))) void *foo() {
>> >> >> >> >>       return (void *)foo;
>> >> >> >> >>     }
>> >> >> >> >>
>> >> >> >> >>     // gcc -fpic -shared -fuse-ld=bfd
>> >> >> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> >>
>> >> >> >> >> The new behavior matches arm, aarch64 (commit
>> >> >> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
>> >> >> >> >> linkers: gold and ld.lld.
>> >> >> >> >>
>> >> >> >> >> Note: if some code tries to use direct access relocations to take the
>> >> >> >> >> address of foo, the pointer equality will break, but the error should be
>> >> >> >> >> reported on the executable link, not on the innocent shared object link.
>> >> >> >> >> glibc 2.36 will give a warning at relocation resolving time.
>> >> >> >> >
>> >> >> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
>> >> >> >> >-z  indirect-extern-access with -shared by default instead?
>> >> >> >>
>> >> >> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
>> >> >> >> bfd/elf-properties.c:654 will create a
>> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
>> >> >> >> This will probably be unexpected (and check-ld will have 280+ failures).
>> >> >> >
>> >> >> >This is normal when the default behavior is changed.  You can pass
>> >> >> >-z noindirect-extern-access to these testcases.
>> >> >>
>> >> >> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
>> >> >> significant behavior change and may unnecessarily break user programs
>> >> >> (glibc will report an error instead of a warning).
>> >> >
>> >> >If glibc reports an error, it is a real bug with unknown consequences
>> >> >when the copy in the executable is out of sync with the protected
>> >> >symbol in the shared library,
>> >>
>> >> Not necessary.
>> >>
>> >> In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
>> >> 1 (copy relocations) and 2 (non-zero value of an undefined function
>> >> symbol) on
>> >> https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html
>> >>
>> >> 2 does not necessarily cause a problem. In many cases it doesn't as
>> >> function pointer equality is not an invariant a program relies upon
>> >> (at least, for many functions, the property is not used). My previous
>> >> comment has mentioned two cases.
>> >>
>> >> 1 likely causes a problem, but technically the shared object can define
>> >> a protected data symbol without accessing it..
>> >
>> >These are unknown consequences.   We don't know what the worst
>> >cases are.
>>
>> They are, just like when a shared object is linked with -Bsymbolic.
>
>They have to deal with it since it is done on purpose.
>
>> This patch focuses on changing the x86 default to a sane value (matching
>> aarch64/arm/powerpc64/riscv/etc) and enabling future removal of
>> `extern_protected_data`.  If you want to switch to
>> indirect-extern-access default for x86, while I think unnecessary, I will not object.
>
>extern_protected_data can be safely removed only when
>direct access to external symbols are disallowed.   We can't
>have both ways.

Just define has_no_copy_on_protected to 1 to catch the usage at link
time.  ld's aarch64 port has such an error by default.  gold and ld.lld
has such an error for a long time now.

We don't need to worry about whether this stricter behavior breaks user
programs.  As is, protected symbol using GCC+binutils provides no
benefit.  Programs just avoid protected data symbols.

>> But I'd note that we aren't really ready for the GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS default.
>> One major issue: -fPIE is widely used nowadays and GCC>=5 has the PIE copy relocation "regression".
>
>-fno-PIE still has copy relocation.

On a Linux distribution, -fno-PIE objects have largely vanished (due to PIE hardening).
So for many shared objects protected symbols can start to be used.

For the very few -fno-PIE exceptions, ask them to add an option. (This
is similar to: distros keep pushing new security hardening options and
some projects need to opt out them.)

>> (My https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html
>> will fix it for future GCC, but the patch seems to get stuck since 2021-05-11.)
>>
>> >> >> If the executable takes the address of a protected function defined in a
>> >> >> shared object, it may or may not cause a pointer equality problem (the
>> >> >> shared object may not take the address) and the problem (if exists) may or
>> >> >> may not be a broken invariance to the program (it may not expect pointer
>> >> >> equality).
>> >> >>
>> >> >> All of aarch64/arm/powerpc64/riscv (likely most except x86, but I
>> >> >> haven't enumerated) consider a protected data symbol local in -shared
>> >> >> links. x86 did so a while ago (before 2015?).  (For
>> >> >> aarch64/arm/powerpc64/riscv, I wish that we never need
>> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. The property will just
>> >> >> waste some bytes in every shared object without carrying much
>> >> >> information.)
>> >> >>
>> >> >> The 280+ failures in check-ld due to the default
>> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS need to be considered as
>> >> >> well.
>> >> >>
>> >> >> >> >> With this change, `#define elf_backend_extern_protected_data 1` is no
>> >> >> >> >> longer effective.  Just remove it.
>> >> >> >> >>
>> >> >> >> >> Remove the test "Run protected-func-1 without PIE" since -fno-pic
>> >> >> >> >> address taken operation in the executable doesn't work with protected
>> >> >> >> >> symbol in a shared object by default.  Similarly, remove
>> >> >> >> >> protected-data-1a and protected-data-1b.  protected-data-1b can be made
>> >> >> >> >> working by removing HAVE_LD_PIE_COPYRELOC from GCC
>> >> >> >> >> (https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
>> >> >> >> >> ---
>> >> >> >> >>  bfd/elf32-i386.c                      |  1 -
>> >> >> >> >>  bfd/elf64-x86-64.c                    |  1 -
>> >> >> >> >>  bfd/elfxx-x86.c                       |  2 +-
>> >> >> >> >>  ld/testsuite/ld-i386/protected1.d     |  4 +++-
>> >> >> >> >>  ld/testsuite/ld-i386/protected3.d     |  2 +-
>> >> >> >> >>  ld/testsuite/ld-i386/protected6a.d    |  4 +++-
>> >> >> >> >>  ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
>> >> >> >> >>  ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
>> >> >> >> >>  ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
>> >> >> >> >>  ld/testsuite/ld-x86-64/protected3.d   |  2 +-
>> >> >> >> >>  ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
>> >> >> >> >>  ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
>> >> >> >> >>  ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
>> >> >> >> >>  13 files changed, 24 insertions(+), 39 deletions(-)
>> >> >> >> >>
>> >> >> >> >> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
>> >> >> >> >> index e4106d9fd3b..c3c46795731 100644
>> >> >> >> >> --- a/bfd/elf32-i386.c
>> >> >> >> >> +++ b/bfd/elf32-i386.c
>> >> >> >> >> @@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
>> >> >> >> >>  #define elf_backend_got_header_size    12
>> >> >> >> >>  #define elf_backend_plt_alignment      4
>> >> >> >> >>  #define elf_backend_dtrel_excludes_plt 1
>> >> >> >> >> -#define elf_backend_extern_protected_data 1
>> >> >> >> >>  #define elf_backend_caches_rawsize     1
>> >> >> >> >>  #define elf_backend_want_dynrelro      1
>> >> >> >> >>
>> >> >> >> >> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
>> >> >> >> >> index 6154a70bdd7..aaa5f1496b9 100644
>> >> >> >> >> --- a/bfd/elf64-x86-64.c
>> >> >> >> >> +++ b/bfd/elf64-x86-64.c
>> >> >> >> >> @@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
>> >> >> >> >>  #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
>> >> >> >> >>  #define elf_backend_rela_normal                    1
>> >> >> >> >>  #define elf_backend_plt_alignment          4
>> >> >> >> >> -#define elf_backend_extern_protected_data   1
>> >> >> >> >>  #define elf_backend_caches_rawsize         1
>> >> >> >> >>  #define elf_backend_dtrel_excludes_plt     1
>> >> >> >> >>  #define elf_backend_want_dynrelro          1
>> >> >> >> >> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
>> >> >> >> >> index acb2cc8528d..18f3d335458 100644
>> >> >> >> >> --- a/bfd/elfxx-x86.c
>> >> >> >> >> +++ b/bfd/elfxx-x86.c
>> >> >> >> >> @@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
>> >> >> >> >>       2. When building executable, there is no dynamic linker.  Or
>> >> >> >> >>       3. or "-z nodynamic-undefined-weak" is used.
>> >> >> >> >>     */
>> >> >> >> >> -  if (SYMBOL_REFERENCES_LOCAL (info, h)
>> >> >> >> >> +  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
>> >> >> >> >>        || (h->root.type == bfd_link_hash_undefweak
>> >> >> >> >>           && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
>> >> >> >> >>               || (bfd_link_executable (info)
>> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
>> >> >> >> >> index a3cb5cef140..531645b8fe8 100644
>> >> >> >> >> --- a/ld/testsuite/ld-i386/protected1.d
>> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected1.d
>> >> >> >> >> @@ -1,3 +1,5 @@
>> >> >> >> >>  #as: --32
>> >> >> >> >>  #ld: -shared -melf_i386
>> >> >> >> >> -#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
>> >> >> >> >> +#readelf: -rW
>> >> >> >> >> +#...
>> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
>> >> >> >> >> index c3a6888d900..77367c4738f 100644
>> >> >> >> >> --- a/ld/testsuite/ld-i386/protected3.d
>> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected3.d
>> >> >> >> >> @@ -8,7 +8,7 @@
>> >> >> >> >>  Disassembly of section .text:
>> >> >> >> >>
>> >> >> >> >>  0+[a-f0-9]+ <bar>:
>> >> >> >> >> -[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
>> >> >> >> >> +[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
>> >> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
>> >> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
>> >> >> >> >>  #pass
>> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
>> >> >> >> >> index 7dc350432f4..4d3873239f9 100644
>> >> >> >> >> --- a/ld/testsuite/ld-i386/protected6a.d
>> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected6a.d
>> >> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >> >>  #source: protected6.s
>> >> >> >> >>  #as: --32
>> >> >> >> >>  #ld: -shared -melf_i386
>> >> >> >> >> -#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
>> >> >> >> >> +#readelf: -rW
>> >> >> >> >> +#...
>> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> >> >> index 130611ddf49..1f49b655f7d 100644
>> >> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >> >>  #source: pr24151a.s
>> >> >> >> >>  #as: --x32
>> >> >> >> >>  #ld: -shared -melf32_x86_64
>> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> >> +#readelf: -rW
>> >> >> >> >> +#...
>> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> >> >> index 783b85a1a6f..6c48e383e01 100644
>> >> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> >> >> @@ -1,3 +1,5 @@
>> >> >> >> >>  #as: --64
>> >> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> >> +#readelf: -rW
>> >> >> >> >> +#...
>> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
>> >> >> >> >> index 783b85a1a6f..6c48e383e01 100644
>> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected1.d
>> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected1.d
>> >> >> >> >> @@ -1,3 +1,5 @@
>> >> >> >> >>  #as: --64
>> >> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> >> +#readelf: -rW
>> >> >> >> >> +#...
>> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
>> >> >> >> >> index 57950e4d6b6..ba63991582f 100644
>> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected3.d
>> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected3.d
>> >> >> >> >> @@ -8,7 +8,7 @@
>> >> >> >> >>  Disassembly of section .text:
>> >> >> >> >>
>> >> >> >> >>  0+[a-f0-9]+ <bar>:
>> >> >> >> >> -[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>> >> >> >> >> +[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>> >> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
>> >> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
>> >> >> >> >>  #pass
>> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> >> >> index 3a7963ffd2f..50d6430b577 100644
>> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >> >>  #source: protected6.s
>> >> >> >> >>  #as: --64
>> >> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
>> >> >> >> >> +#readelf: -rW
>> >> >> >> >> +#...
>> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> >> >> index 3082084a7b8..3974246a2a8 100644
>> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >> >>  #source: protected7.s
>> >> >> >> >>  #as: --64
>> >> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
>> >> >> >> >> +#readelf: -rW
>> >> >> >> >> +#...
>> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> >> >> index 5e5636bcebe..a096c0b9d0f 100644
>> >> >> >> >> --- a/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> >> >> @@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
>> >> >> >> >>             "pr23997" \
>> >> >> >> >>             "pass.out" \
>> >> >> >> >>         ] \
>> >> >> >> >> -       [list \
>> >> >> >> >> -           "Run protected-func-1 without PIE" \
>> >> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
>> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> >> >> -           { protected-func-1b.c } \
>> >> >> >> >> -           "protected-func-1a" \
>> >> >> >> >> -           "pass.out" \
>> >> >> >> >> -           "$NOPIE_CFLAGS" \
>> >> >> >> >> -       ] \
>> >> >> >> >>         [list \
>> >> >> >> >>             "Run protected-func-1 with PIE" \
>> >> >> >> >>             "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
>> >> >> >> >> @@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
>> >> >> >> >>             "pass.out" \
>> >> >> >> >>             "-fPIE" \
>> >> >> >> >>         ] \
>> >> >> >> >> -       [list \
>> >> >> >> >> -           "Run protected-data-1a without PIE" \
>> >> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
>> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> >> >> -           { protected-data-1b.c } \
>> >> >> >> >> -           "protected-data-1a" \
>> >> >> >> >> -           "pass.out" \
>> >> >> >> >> -           "$NOPIE_CFLAGS" \
>> >> >> >> >> -       ] \
>> >> >> >> >> -       [list \
>> >> >> >> >> -           "Run protected-data-1b with PIE" \
>> >> >> >> >> -           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
>> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> >> >> -           { protected-data-1b.c } \
>> >> >> >> >> -           "protected-data-1b" \
>> >> >> >> >> -           "pass.out" \
>> >> >> >> >> -           "-fPIE" \
>> >> >> >> >> -       ] \
>> >> >> >> >>         [list \
>> >> >> >> >>             "Run protected-data-2a without PIE" \
>> >> >> >> >>             "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
>> >> >> >> >> --
>> >> >> >> >> 2.37
>> >> >> >> >>
>> >> >> >> >
>> >> >> >> >
>> >> >> >> >--
>> >> >> >> >H.J.
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> >--
>> >> >> >H.J.
>> >> >
>> >> >
>> >> >
>> >> >--
>> >> >H.J.
>> >
>> >
>> >
>> >--
>> >H.J.
>
>
>
>-- 
>H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-28  3:07                   ` Fangrui Song
@ 2022-06-28  3:24                     ` H.J. Lu
  2022-06-28  3:43                       ` Fangrui Song
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2022-06-28  3:24 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

On Mon, Jun 27, 2022 at 8:07 PM Fangrui Song <i@maskray.me> wrote:
>
> On 2022-06-27, H.J. Lu wrote:
> >On Mon, Jun 27, 2022 at 11:46 AM Fangrui Song <i@maskray.me> wrote:
> >>
> >> On 2022-06-27, H.J. Lu wrote:
> >> >On Mon, Jun 27, 2022 at 10:53 AM Fangrui Song <i@maskray.me> wrote:
> >> >>
> >> >> On 2022-06-27, H.J. Lu wrote:
> >> >> >On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
> >> >> >>
> >> >> >> On 2022-06-27, H.J. Lu wrote:
> >> >> >> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
> >> >> >> >>
> >> >> >> >> On 2022-06-26, H.J. Lu wrote:
> >> >> >> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
> >> >> >> >> >>
> >> >> >> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
> >> >> >> >> >> 2 noticeable effects for -shared:
> >> >> >> >> >>
> >> >> >> >> >> * GOT-generating relocations referencing a protected data symbol no
> >> >> >> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
> >> >> >> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
> >> >> >> >> >>   confusing diagnostic below.
> >> >> >> >> >>
> >> >> >> >> >>     __attribute__((visibility("protected"))) void *foo() {
> >> >> >> >> >>       return (void *)foo;
> >> >> >> >> >>     }
> >> >> >> >> >>
> >> >> >> >> >>     // gcc -fpic -shared -fuse-ld=bfd
> >> >> >> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> >> >>
> >> >> >> >> >> The new behavior matches arm, aarch64 (commit
> >> >> >> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
> >> >> >> >> >> linkers: gold and ld.lld.
> >> >> >> >> >>
> >> >> >> >> >> Note: if some code tries to use direct access relocations to take the
> >> >> >> >> >> address of foo, the pointer equality will break, but the error should be
> >> >> >> >> >> reported on the executable link, not on the innocent shared object link.
> >> >> >> >> >> glibc 2.36 will give a warning at relocation resolving time.
> >> >> >> >> >
> >> >> >> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
> >> >> >> >> >-z  indirect-extern-access with -shared by default instead?
> >> >> >> >>
> >> >> >> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
> >> >> >> >> bfd/elf-properties.c:654 will create a
> >> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
> >> >> >> >> This will probably be unexpected (and check-ld will have 280+ failures).
> >> >> >> >
> >> >> >> >This is normal when the default behavior is changed.  You can pass
> >> >> >> >-z noindirect-extern-access to these testcases.
> >> >> >>
> >> >> >> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
> >> >> >> significant behavior change and may unnecessarily break user programs
> >> >> >> (glibc will report an error instead of a warning).
> >> >> >
> >> >> >If glibc reports an error, it is a real bug with unknown consequences
> >> >> >when the copy in the executable is out of sync with the protected
> >> >> >symbol in the shared library,
> >> >>
> >> >> Not necessary.
> >> >>
> >> >> In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
> >> >> 1 (copy relocations) and 2 (non-zero value of an undefined function
> >> >> symbol) on
> >> >> https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html
> >> >>
> >> >> 2 does not necessarily cause a problem. In many cases it doesn't as
> >> >> function pointer equality is not an invariant a program relies upon
> >> >> (at least, for many functions, the property is not used). My previous
> >> >> comment has mentioned two cases.
> >> >>
> >> >> 1 likely causes a problem, but technically the shared object can define
> >> >> a protected data symbol without accessing it..
> >> >
> >> >These are unknown consequences.   We don't know what the worst
> >> >cases are.
> >>
> >> They are, just like when a shared object is linked with -Bsymbolic.
> >
> >They have to deal with it since it is done on purpose.
> >
> >> This patch focuses on changing the x86 default to a sane value (matching
> >> aarch64/arm/powerpc64/riscv/etc) and enabling future removal of
> >> `extern_protected_data`.  If you want to switch to
> >> indirect-extern-access default for x86, while I think unnecessary, I will not object.
> >
> >extern_protected_data can be safely removed only when
> >direct access to external symbols are disallowed.   We can't
> >have both ways.
>
> Just define has_no_copy_on_protected to 1 to catch the usage at link

This is the same as using -z indirect-extern-access on executable.

> time.  ld's aarch64 port has such an error by default.  gold and ld.lld
> has such an error for a long time now.
>
> We don't need to worry about whether this stricter behavior breaks user
> programs.  As is, protected symbol using GCC+binutils provides no
> benefit.  Programs just avoid protected data symbols.

Then there should be no problems with
GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
I'd like to disallow copy relocation on protected symbols at run-time
when there are unknown consequences.

> >> But I'd note that we aren't really ready for the GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS default.
> >> One major issue: -fPIE is widely used nowadays and GCC>=5 has the PIE copy relocation "regression".
> >
> >-fno-PIE still has copy relocation.
>
> On a Linux distribution, -fno-PIE objects have largely vanished (due to PIE hardening).
> So for many shared objects protected symbols can start to be used.
>
> For the very few -fno-PIE exceptions, ask them to add an option. (This
> is similar to: distros keep pushing new security hardening options and
> some projects need to opt out them.)
>
> >> (My https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html
> >> will fix it for future GCC, but the patch seems to get stuck since 2021-05-11.)
> >>
> >> >> >> If the executable takes the address of a protected function defined in a
> >> >> >> shared object, it may or may not cause a pointer equality problem (the
> >> >> >> shared object may not take the address) and the problem (if exists) may or
> >> >> >> may not be a broken invariance to the program (it may not expect pointer
> >> >> >> equality).
> >> >> >>
> >> >> >> All of aarch64/arm/powerpc64/riscv (likely most except x86, but I
> >> >> >> haven't enumerated) consider a protected data symbol local in -shared
> >> >> >> links. x86 did so a while ago (before 2015?).  (For
> >> >> >> aarch64/arm/powerpc64/riscv, I wish that we never need
> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. The property will just
> >> >> >> waste some bytes in every shared object without carrying much
> >> >> >> information.)
> >> >> >>
> >> >> >> The 280+ failures in check-ld due to the default
> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS need to be considered as
> >> >> >> well.
> >> >> >>
> >> >> >> >> >> With this change, `#define elf_backend_extern_protected_data 1` is no
> >> >> >> >> >> longer effective.  Just remove it.
> >> >> >> >> >>
> >> >> >> >> >> Remove the test "Run protected-func-1 without PIE" since -fno-pic
> >> >> >> >> >> address taken operation in the executable doesn't work with protected
> >> >> >> >> >> symbol in a shared object by default.  Similarly, remove
> >> >> >> >> >> protected-data-1a and protected-data-1b.  protected-data-1b can be made
> >> >> >> >> >> working by removing HAVE_LD_PIE_COPYRELOC from GCC
> >> >> >> >> >> (https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
> >> >> >> >> >> ---
> >> >> >> >> >>  bfd/elf32-i386.c                      |  1 -
> >> >> >> >> >>  bfd/elf64-x86-64.c                    |  1 -
> >> >> >> >> >>  bfd/elfxx-x86.c                       |  2 +-
> >> >> >> >> >>  ld/testsuite/ld-i386/protected1.d     |  4 +++-
> >> >> >> >> >>  ld/testsuite/ld-i386/protected3.d     |  2 +-
> >> >> >> >> >>  ld/testsuite/ld-i386/protected6a.d    |  4 +++-
> >> >> >> >> >>  ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
> >> >> >> >> >>  ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected3.d   |  2 +-
> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
> >> >> >> >> >>  ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
> >> >> >> >> >>  13 files changed, 24 insertions(+), 39 deletions(-)
> >> >> >> >> >>
> >> >> >> >> >> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> >> >> >> >> >> index e4106d9fd3b..c3c46795731 100644
> >> >> >> >> >> --- a/bfd/elf32-i386.c
> >> >> >> >> >> +++ b/bfd/elf32-i386.c
> >> >> >> >> >> @@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
> >> >> >> >> >>  #define elf_backend_got_header_size    12
> >> >> >> >> >>  #define elf_backend_plt_alignment      4
> >> >> >> >> >>  #define elf_backend_dtrel_excludes_plt 1
> >> >> >> >> >> -#define elf_backend_extern_protected_data 1
> >> >> >> >> >>  #define elf_backend_caches_rawsize     1
> >> >> >> >> >>  #define elf_backend_want_dynrelro      1
> >> >> >> >> >>
> >> >> >> >> >> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> >> >> >> >> >> index 6154a70bdd7..aaa5f1496b9 100644
> >> >> >> >> >> --- a/bfd/elf64-x86-64.c
> >> >> >> >> >> +++ b/bfd/elf64-x86-64.c
> >> >> >> >> >> @@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
> >> >> >> >> >>  #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
> >> >> >> >> >>  #define elf_backend_rela_normal                    1
> >> >> >> >> >>  #define elf_backend_plt_alignment          4
> >> >> >> >> >> -#define elf_backend_extern_protected_data   1
> >> >> >> >> >>  #define elf_backend_caches_rawsize         1
> >> >> >> >> >>  #define elf_backend_dtrel_excludes_plt     1
> >> >> >> >> >>  #define elf_backend_want_dynrelro          1
> >> >> >> >> >> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
> >> >> >> >> >> index acb2cc8528d..18f3d335458 100644
> >> >> >> >> >> --- a/bfd/elfxx-x86.c
> >> >> >> >> >> +++ b/bfd/elfxx-x86.c
> >> >> >> >> >> @@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
> >> >> >> >> >>       2. When building executable, there is no dynamic linker.  Or
> >> >> >> >> >>       3. or "-z nodynamic-undefined-weak" is used.
> >> >> >> >> >>     */
> >> >> >> >> >> -  if (SYMBOL_REFERENCES_LOCAL (info, h)
> >> >> >> >> >> +  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
> >> >> >> >> >>        || (h->root.type == bfd_link_hash_undefweak
> >> >> >> >> >>           && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
> >> >> >> >> >>               || (bfd_link_executable (info)
> >> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
> >> >> >> >> >> index a3cb5cef140..531645b8fe8 100644
> >> >> >> >> >> --- a/ld/testsuite/ld-i386/protected1.d
> >> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected1.d
> >> >> >> >> >> @@ -1,3 +1,5 @@
> >> >> >> >> >>  #as: --32
> >> >> >> >> >>  #ld: -shared -melf_i386
> >> >> >> >> >> -#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
> >> >> >> >> >> +#readelf: -rW
> >> >> >> >> >> +#...
> >> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
> >> >> >> >> >> index c3a6888d900..77367c4738f 100644
> >> >> >> >> >> --- a/ld/testsuite/ld-i386/protected3.d
> >> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected3.d
> >> >> >> >> >> @@ -8,7 +8,7 @@
> >> >> >> >> >>  Disassembly of section .text:
> >> >> >> >> >>
> >> >> >> >> >>  0+[a-f0-9]+ <bar>:
> >> >> >> >> >> -[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
> >> >> >> >> >> +[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
> >> >> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
> >> >> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
> >> >> >> >> >>  #pass
> >> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
> >> >> >> >> >> index 7dc350432f4..4d3873239f9 100644
> >> >> >> >> >> --- a/ld/testsuite/ld-i386/protected6a.d
> >> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected6a.d
> >> >> >> >> >> @@ -1,4 +1,6 @@
> >> >> >> >> >>  #source: protected6.s
> >> >> >> >> >>  #as: --32
> >> >> >> >> >>  #ld: -shared -melf_i386
> >> >> >> >> >> -#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
> >> >> >> >> >> +#readelf: -rW
> >> >> >> >> >> +#...
> >> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> >> >> >> index 130611ddf49..1f49b655f7d 100644
> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> >> >> >> @@ -1,4 +1,6 @@
> >> >> >> >> >>  #source: pr24151a.s
> >> >> >> >> >>  #as: --x32
> >> >> >> >> >>  #ld: -shared -melf32_x86_64
> >> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> >> >> +#readelf: -rW
> >> >> >> >> >> +#...
> >> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> >> >> >> index 783b85a1a6f..6c48e383e01 100644
> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> >> >> >> @@ -1,3 +1,5 @@
> >> >> >> >> >>  #as: --64
> >> >> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> >> >> +#readelf: -rW
> >> >> >> >> >> +#...
> >> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
> >> >> >> >> >> index 783b85a1a6f..6c48e383e01 100644
> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected1.d
> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected1.d
> >> >> >> >> >> @@ -1,3 +1,5 @@
> >> >> >> >> >>  #as: --64
> >> >> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> >> >> +#readelf: -rW
> >> >> >> >> >> +#...
> >> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
> >> >> >> >> >> index 57950e4d6b6..ba63991582f 100644
> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected3.d
> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected3.d
> >> >> >> >> >> @@ -8,7 +8,7 @@
> >> >> >> >> >>  Disassembly of section .text:
> >> >> >> >> >>
> >> >> >> >> >>  0+[a-f0-9]+ <bar>:
> >> >> >> >> >> -[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> >> >> >> >> >> +[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> >> >> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
> >> >> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
> >> >> >> >> >>  #pass
> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
> >> >> >> >> >> index 3a7963ffd2f..50d6430b577 100644
> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected6a.d
> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected6a.d
> >> >> >> >> >> @@ -1,4 +1,6 @@
> >> >> >> >> >>  #source: protected6.s
> >> >> >> >> >>  #as: --64
> >> >> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
> >> >> >> >> >> +#readelf: -rW
> >> >> >> >> >> +#...
> >> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
> >> >> >> >> >> index 3082084a7b8..3974246a2a8 100644
> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected7a.d
> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected7a.d
> >> >> >> >> >> @@ -1,4 +1,6 @@
> >> >> >> >> >>  #source: protected7.s
> >> >> >> >> >>  #as: --64
> >> >> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
> >> >> >> >> >> +#readelf: -rW
> >> >> >> >> >> +#...
> >> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> >> >> >> index 5e5636bcebe..a096c0b9d0f 100644
> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> >> >> >> @@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
> >> >> >> >> >>             "pr23997" \
> >> >> >> >> >>             "pass.out" \
> >> >> >> >> >>         ] \
> >> >> >> >> >> -       [list \
> >> >> >> >> >> -           "Run protected-func-1 without PIE" \
> >> >> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
> >> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> >> >> >> -           { protected-func-1b.c } \
> >> >> >> >> >> -           "protected-func-1a" \
> >> >> >> >> >> -           "pass.out" \
> >> >> >> >> >> -           "$NOPIE_CFLAGS" \
> >> >> >> >> >> -       ] \
> >> >> >> >> >>         [list \
> >> >> >> >> >>             "Run protected-func-1 with PIE" \
> >> >> >> >> >>             "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
> >> >> >> >> >> @@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
> >> >> >> >> >>             "pass.out" \
> >> >> >> >> >>             "-fPIE" \
> >> >> >> >> >>         ] \
> >> >> >> >> >> -       [list \
> >> >> >> >> >> -           "Run protected-data-1a without PIE" \
> >> >> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
> >> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> >> >> >> -           { protected-data-1b.c } \
> >> >> >> >> >> -           "protected-data-1a" \
> >> >> >> >> >> -           "pass.out" \
> >> >> >> >> >> -           "$NOPIE_CFLAGS" \
> >> >> >> >> >> -       ] \
> >> >> >> >> >> -       [list \
> >> >> >> >> >> -           "Run protected-data-1b with PIE" \
> >> >> >> >> >> -           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
> >> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> >> >> >> -           { protected-data-1b.c } \
> >> >> >> >> >> -           "protected-data-1b" \
> >> >> >> >> >> -           "pass.out" \
> >> >> >> >> >> -           "-fPIE" \
> >> >> >> >> >> -       ] \
> >> >> >> >> >>         [list \
> >> >> >> >> >>             "Run protected-data-2a without PIE" \
> >> >> >> >> >>             "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
> >> >> >> >> >> --
> >> >> >> >> >> 2.37
> >> >> >> >> >>
> >> >> >> >> >
> >> >> >> >> >
> >> >> >> >> >--
> >> >> >> >> >H.J.
> >> >> >> >
> >> >> >> >
> >> >> >> >
> >> >> >> >--
> >> >> >> >H.J.
> >> >> >
> >> >> >
> >> >> >
> >> >> >--
> >> >> >H.J.
> >> >
> >> >
> >> >
> >> >--
> >> >H.J.
> >
> >
> >
> >--
> >H.J.



-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-28  3:24                     ` H.J. Lu
@ 2022-06-28  3:43                       ` Fangrui Song
  2022-06-28  3:51                         ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Fangrui Song @ 2022-06-28  3:43 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On 2022-06-27, H.J. Lu wrote:
>On Mon, Jun 27, 2022 at 8:07 PM Fangrui Song <i@maskray.me> wrote:
>>
>> On 2022-06-27, H.J. Lu wrote:
>> >On Mon, Jun 27, 2022 at 11:46 AM Fangrui Song <i@maskray.me> wrote:
>> >>
>> >> On 2022-06-27, H.J. Lu wrote:
>> >> >On Mon, Jun 27, 2022 at 10:53 AM Fangrui Song <i@maskray.me> wrote:
>> >> >>
>> >> >> On 2022-06-27, H.J. Lu wrote:
>> >> >> >On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
>> >> >> >>
>> >> >> >> On 2022-06-27, H.J. Lu wrote:
>> >> >> >> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
>> >> >> >> >>
>> >> >> >> >> On 2022-06-26, H.J. Lu wrote:
>> >> >> >> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
>> >> >> >> >> >>
>> >> >> >> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
>> >> >> >> >> >> 2 noticeable effects for -shared:
>> >> >> >> >> >>
>> >> >> >> >> >> * GOT-generating relocations referencing a protected data symbol no
>> >> >> >> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
>> >> >> >> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
>> >> >> >> >> >>   confusing diagnostic below.
>> >> >> >> >> >>
>> >> >> >> >> >>     __attribute__((visibility("protected"))) void *foo() {
>> >> >> >> >> >>       return (void *)foo;
>> >> >> >> >> >>     }
>> >> >> >> >> >>
>> >> >> >> >> >>     // gcc -fpic -shared -fuse-ld=bfd
>> >> >> >> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> >> >>
>> >> >> >> >> >> The new behavior matches arm, aarch64 (commit
>> >> >> >> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
>> >> >> >> >> >> linkers: gold and ld.lld.
>> >> >> >> >> >>
>> >> >> >> >> >> Note: if some code tries to use direct access relocations to take the
>> >> >> >> >> >> address of foo, the pointer equality will break, but the error should be
>> >> >> >> >> >> reported on the executable link, not on the innocent shared object link.
>> >> >> >> >> >> glibc 2.36 will give a warning at relocation resolving time.
>> >> >> >> >> >
>> >> >> >> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
>> >> >> >> >> >-z  indirect-extern-access with -shared by default instead?
>> >> >> >> >>
>> >> >> >> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
>> >> >> >> >> bfd/elf-properties.c:654 will create a
>> >> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
>> >> >> >> >> This will probably be unexpected (and check-ld will have 280+ failures).
>> >> >> >> >
>> >> >> >> >This is normal when the default behavior is changed.  You can pass
>> >> >> >> >-z noindirect-extern-access to these testcases.
>> >> >> >>
>> >> >> >> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
>> >> >> >> significant behavior change and may unnecessarily break user programs
>> >> >> >> (glibc will report an error instead of a warning).
>> >> >> >
>> >> >> >If glibc reports an error, it is a real bug with unknown consequences
>> >> >> >when the copy in the executable is out of sync with the protected
>> >> >> >symbol in the shared library,
>> >> >>
>> >> >> Not necessary.
>> >> >>
>> >> >> In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
>> >> >> 1 (copy relocations) and 2 (non-zero value of an undefined function
>> >> >> symbol) on
>> >> >> https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html
>> >> >>
>> >> >> 2 does not necessarily cause a problem. In many cases it doesn't as
>> >> >> function pointer equality is not an invariant a program relies upon
>> >> >> (at least, for many functions, the property is not used). My previous
>> >> >> comment has mentioned two cases.
>> >> >>
>> >> >> 1 likely causes a problem, but technically the shared object can define
>> >> >> a protected data symbol without accessing it..
>> >> >
>> >> >These are unknown consequences.   We don't know what the worst
>> >> >cases are.
>> >>
>> >> They are, just like when a shared object is linked with -Bsymbolic.
>> >
>> >They have to deal with it since it is done on purpose.
>> >
>> >> This patch focuses on changing the x86 default to a sane value (matching
>> >> aarch64/arm/powerpc64/riscv/etc) and enabling future removal of
>> >> `extern_protected_data`.  If you want to switch to
>> >> indirect-extern-access default for x86, while I think unnecessary, I will not object.
>> >
>> >extern_protected_data can be safely removed only when
>> >direct access to external symbols are disallowed.   We can't
>> >have both ways.
>>
>> Just define has_no_copy_on_protected to 1 to catch the usage at link
>
>This is the same as using -z indirect-extern-access on executable.
>
>> time.  ld's aarch64 port has such an error by default.  gold and ld.lld
>> has such an error for a long time now.
>>
>> We don't need to worry about whether this stricter behavior breaks user
>> programs.  As is, protected symbol using GCC+binutils provides no
>> benefit.  Programs just avoid protected data symbols.
>
>Then there should be no problems with
>GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
>I'd like to disallow copy relocation on protected symbols at run-time
>when there are unknown consequences.

Enabling GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS for x86 by default
has these effects:

* 280+ check-ld tests will fail
* The GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note appears
   redundant. It encodes an intention explicit but the intention is
   in ld aarch64, gold (all ports), and lld (all ports) with no extra option.

IMO, we should do these:

* push this commit
* treat elf_has_no_copy_on_protected as always true and remove all GNU_PROPERTY_NO_COPY_ON_PROTECTED

Again, I understand that there is concern about protected data symbols
in shared object.  But as is, nobody uses protected symbols in shared objects.
My

   // gcc -fpic -shared -fuse-ld=bfd
   __attribute__((visibility("protected"))) void *foo() {
     return (void *)foo;
   }

example indicates that protected future symbol is also broken.


>> >> But I'd note that we aren't really ready for the GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS default.
>> >> One major issue: -fPIE is widely used nowadays and GCC>=5 has the PIE copy relocation "regression".
>> >
>> >-fno-PIE still has copy relocation.
>>
>> On a Linux distribution, -fno-PIE objects have largely vanished (due to PIE hardening).
>> So for many shared objects protected symbols can start to be used.
>>
>> For the very few -fno-PIE exceptions, ask them to add an option. (This
>> is similar to: distros keep pushing new security hardening options and
>> some projects need to opt out them.)
>>
>> >> (My https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html
>> >> will fix it for future GCC, but the patch seems to get stuck since 2021-05-11.)
>> >>
>> >> >> >> If the executable takes the address of a protected function defined in a
>> >> >> >> shared object, it may or may not cause a pointer equality problem (the
>> >> >> >> shared object may not take the address) and the problem (if exists) may or
>> >> >> >> may not be a broken invariance to the program (it may not expect pointer
>> >> >> >> equality).
>> >> >> >>
>> >> >> >> All of aarch64/arm/powerpc64/riscv (likely most except x86, but I
>> >> >> >> haven't enumerated) consider a protected data symbol local in -shared
>> >> >> >> links. x86 did so a while ago (before 2015?).  (For
>> >> >> >> aarch64/arm/powerpc64/riscv, I wish that we never need
>> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. The property will just
>> >> >> >> waste some bytes in every shared object without carrying much
>> >> >> >> information.)
>> >> >> >>
>> >> >> >> The 280+ failures in check-ld due to the default
>> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS need to be considered as
>> >> >> >> well.
>> >> >> >>
>> >> >> >> >> >> With this change, `#define elf_backend_extern_protected_data 1` is no
>> >> >> >> >> >> longer effective.  Just remove it.
>> >> >> >> >> >>
>> >> >> >> >> >> Remove the test "Run protected-func-1 without PIE" since -fno-pic
>> >> >> >> >> >> address taken operation in the executable doesn't work with protected
>> >> >> >> >> >> symbol in a shared object by default.  Similarly, remove
>> >> >> >> >> >> protected-data-1a and protected-data-1b.  protected-data-1b can be made
>> >> >> >> >> >> working by removing HAVE_LD_PIE_COPYRELOC from GCC
>> >> >> >> >> >> (https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
>> >> >> >> >> >> ---
>> >> >> >> >> >>  bfd/elf32-i386.c                      |  1 -
>> >> >> >> >> >>  bfd/elf64-x86-64.c                    |  1 -
>> >> >> >> >> >>  bfd/elfxx-x86.c                       |  2 +-
>> >> >> >> >> >>  ld/testsuite/ld-i386/protected1.d     |  4 +++-
>> >> >> >> >> >>  ld/testsuite/ld-i386/protected3.d     |  2 +-
>> >> >> >> >> >>  ld/testsuite/ld-i386/protected6a.d    |  4 +++-
>> >> >> >> >> >>  ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
>> >> >> >> >> >>  ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
>> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
>> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected3.d   |  2 +-
>> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
>> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
>> >> >> >> >> >>  ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
>> >> >> >> >> >>  13 files changed, 24 insertions(+), 39 deletions(-)
>> >> >> >> >> >>
>> >> >> >> >> >> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
>> >> >> >> >> >> index e4106d9fd3b..c3c46795731 100644
>> >> >> >> >> >> --- a/bfd/elf32-i386.c
>> >> >> >> >> >> +++ b/bfd/elf32-i386.c
>> >> >> >> >> >> @@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
>> >> >> >> >> >>  #define elf_backend_got_header_size    12
>> >> >> >> >> >>  #define elf_backend_plt_alignment      4
>> >> >> >> >> >>  #define elf_backend_dtrel_excludes_plt 1
>> >> >> >> >> >> -#define elf_backend_extern_protected_data 1
>> >> >> >> >> >>  #define elf_backend_caches_rawsize     1
>> >> >> >> >> >>  #define elf_backend_want_dynrelro      1
>> >> >> >> >> >>
>> >> >> >> >> >> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
>> >> >> >> >> >> index 6154a70bdd7..aaa5f1496b9 100644
>> >> >> >> >> >> --- a/bfd/elf64-x86-64.c
>> >> >> >> >> >> +++ b/bfd/elf64-x86-64.c
>> >> >> >> >> >> @@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
>> >> >> >> >> >>  #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
>> >> >> >> >> >>  #define elf_backend_rela_normal                    1
>> >> >> >> >> >>  #define elf_backend_plt_alignment          4
>> >> >> >> >> >> -#define elf_backend_extern_protected_data   1
>> >> >> >> >> >>  #define elf_backend_caches_rawsize         1
>> >> >> >> >> >>  #define elf_backend_dtrel_excludes_plt     1
>> >> >> >> >> >>  #define elf_backend_want_dynrelro          1
>> >> >> >> >> >> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
>> >> >> >> >> >> index acb2cc8528d..18f3d335458 100644
>> >> >> >> >> >> --- a/bfd/elfxx-x86.c
>> >> >> >> >> >> +++ b/bfd/elfxx-x86.c
>> >> >> >> >> >> @@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
>> >> >> >> >> >>       2. When building executable, there is no dynamic linker.  Or
>> >> >> >> >> >>       3. or "-z nodynamic-undefined-weak" is used.
>> >> >> >> >> >>     */
>> >> >> >> >> >> -  if (SYMBOL_REFERENCES_LOCAL (info, h)
>> >> >> >> >> >> +  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
>> >> >> >> >> >>        || (h->root.type == bfd_link_hash_undefweak
>> >> >> >> >> >>           && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
>> >> >> >> >> >>               || (bfd_link_executable (info)
>> >> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
>> >> >> >> >> >> index a3cb5cef140..531645b8fe8 100644
>> >> >> >> >> >> --- a/ld/testsuite/ld-i386/protected1.d
>> >> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected1.d
>> >> >> >> >> >> @@ -1,3 +1,5 @@
>> >> >> >> >> >>  #as: --32
>> >> >> >> >> >>  #ld: -shared -melf_i386
>> >> >> >> >> >> -#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
>> >> >> >> >> >> +#readelf: -rW
>> >> >> >> >> >> +#...
>> >> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
>> >> >> >> >> >> index c3a6888d900..77367c4738f 100644
>> >> >> >> >> >> --- a/ld/testsuite/ld-i386/protected3.d
>> >> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected3.d
>> >> >> >> >> >> @@ -8,7 +8,7 @@
>> >> >> >> >> >>  Disassembly of section .text:
>> >> >> >> >> >>
>> >> >> >> >> >>  0+[a-f0-9]+ <bar>:
>> >> >> >> >> >> -[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
>> >> >> >> >> >> +[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
>> >> >> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
>> >> >> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
>> >> >> >> >> >>  #pass
>> >> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
>> >> >> >> >> >> index 7dc350432f4..4d3873239f9 100644
>> >> >> >> >> >> --- a/ld/testsuite/ld-i386/protected6a.d
>> >> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected6a.d
>> >> >> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >> >> >>  #source: protected6.s
>> >> >> >> >> >>  #as: --32
>> >> >> >> >> >>  #ld: -shared -melf_i386
>> >> >> >> >> >> -#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
>> >> >> >> >> >> +#readelf: -rW
>> >> >> >> >> >> +#...
>> >> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> >> >> >> index 130611ddf49..1f49b655f7d 100644
>> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >> >> >>  #source: pr24151a.s
>> >> >> >> >> >>  #as: --x32
>> >> >> >> >> >>  #ld: -shared -melf32_x86_64
>> >> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> >> >> +#readelf: -rW
>> >> >> >> >> >> +#...
>> >> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> >> >> >> index 783b85a1a6f..6c48e383e01 100644
>> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> >> >> >> @@ -1,3 +1,5 @@
>> >> >> >> >> >>  #as: --64
>> >> >> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> >> >> +#readelf: -rW
>> >> >> >> >> >> +#...
>> >> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
>> >> >> >> >> >> index 783b85a1a6f..6c48e383e01 100644
>> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected1.d
>> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected1.d
>> >> >> >> >> >> @@ -1,3 +1,5 @@
>> >> >> >> >> >>  #as: --64
>> >> >> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> >> >> +#readelf: -rW
>> >> >> >> >> >> +#...
>> >> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
>> >> >> >> >> >> index 57950e4d6b6..ba63991582f 100644
>> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected3.d
>> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected3.d
>> >> >> >> >> >> @@ -8,7 +8,7 @@
>> >> >> >> >> >>  Disassembly of section .text:
>> >> >> >> >> >>
>> >> >> >> >> >>  0+[a-f0-9]+ <bar>:
>> >> >> >> >> >> -[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>> >> >> >> >> >> +[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>> >> >> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
>> >> >> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
>> >> >> >> >> >>  #pass
>> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> >> >> >> index 3a7963ffd2f..50d6430b577 100644
>> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >> >> >>  #source: protected6.s
>> >> >> >> >> >>  #as: --64
>> >> >> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
>> >> >> >> >> >> +#readelf: -rW
>> >> >> >> >> >> +#...
>> >> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> >> >> >> index 3082084a7b8..3974246a2a8 100644
>> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >> >> >>  #source: protected7.s
>> >> >> >> >> >>  #as: --64
>> >> >> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
>> >> >> >> >> >> +#readelf: -rW
>> >> >> >> >> >> +#...
>> >> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> >> >> >> index 5e5636bcebe..a096c0b9d0f 100644
>> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> >> >> >> @@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
>> >> >> >> >> >>             "pr23997" \
>> >> >> >> >> >>             "pass.out" \
>> >> >> >> >> >>         ] \
>> >> >> >> >> >> -       [list \
>> >> >> >> >> >> -           "Run protected-func-1 without PIE" \
>> >> >> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
>> >> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> >> >> >> -           { protected-func-1b.c } \
>> >> >> >> >> >> -           "protected-func-1a" \
>> >> >> >> >> >> -           "pass.out" \
>> >> >> >> >> >> -           "$NOPIE_CFLAGS" \
>> >> >> >> >> >> -       ] \
>> >> >> >> >> >>         [list \
>> >> >> >> >> >>             "Run protected-func-1 with PIE" \
>> >> >> >> >> >>             "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
>> >> >> >> >> >> @@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
>> >> >> >> >> >>             "pass.out" \
>> >> >> >> >> >>             "-fPIE" \
>> >> >> >> >> >>         ] \
>> >> >> >> >> >> -       [list \
>> >> >> >> >> >> -           "Run protected-data-1a without PIE" \
>> >> >> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
>> >> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> >> >> >> -           { protected-data-1b.c } \
>> >> >> >> >> >> -           "protected-data-1a" \
>> >> >> >> >> >> -           "pass.out" \
>> >> >> >> >> >> -           "$NOPIE_CFLAGS" \
>> >> >> >> >> >> -       ] \
>> >> >> >> >> >> -       [list \
>> >> >> >> >> >> -           "Run protected-data-1b with PIE" \
>> >> >> >> >> >> -           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
>> >> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> >> >> >> -           { protected-data-1b.c } \
>> >> >> >> >> >> -           "protected-data-1b" \
>> >> >> >> >> >> -           "pass.out" \
>> >> >> >> >> >> -           "-fPIE" \
>> >> >> >> >> >> -       ] \
>> >> >> >> >> >>         [list \
>> >> >> >> >> >>             "Run protected-data-2a without PIE" \
>> >> >> >> >> >>             "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
>> >> >> >> >> >> --
>> >> >> >> >> >> 2.37
>> >> >> >> >> >>
>> >> >> >> >> >
>> >> >> >> >> >
>> >> >> >> >> >--
>> >> >> >> >> >H.J.
>> >> >> >> >
>> >> >> >> >
>> >> >> >> >
>> >> >> >> >--
>> >> >> >> >H.J.
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> >--
>> >> >> >H.J.
>> >> >
>> >> >
>> >> >
>> >> >--
>> >> >H.J.
>> >
>> >
>> >
>> >--
>> >H.J.
>
>
>
>-- 
>H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-28  3:43                       ` Fangrui Song
@ 2022-06-28  3:51                         ` H.J. Lu
  2022-06-28  4:18                           ` Fangrui Song
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2022-06-28  3:51 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

On Mon, Jun 27, 2022 at 8:44 PM Fangrui Song <i@maskray.me> wrote:
>
> On 2022-06-27, H.J. Lu wrote:
> >On Mon, Jun 27, 2022 at 8:07 PM Fangrui Song <i@maskray.me> wrote:
> >>
> >> On 2022-06-27, H.J. Lu wrote:
> >> >On Mon, Jun 27, 2022 at 11:46 AM Fangrui Song <i@maskray.me> wrote:
> >> >>
> >> >> On 2022-06-27, H.J. Lu wrote:
> >> >> >On Mon, Jun 27, 2022 at 10:53 AM Fangrui Song <i@maskray.me> wrote:
> >> >> >>
> >> >> >> On 2022-06-27, H.J. Lu wrote:
> >> >> >> >On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
> >> >> >> >>
> >> >> >> >> On 2022-06-27, H.J. Lu wrote:
> >> >> >> >> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
> >> >> >> >> >>
> >> >> >> >> >> On 2022-06-26, H.J. Lu wrote:
> >> >> >> >> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
> >> >> >> >> >> >>
> >> >> >> >> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
> >> >> >> >> >> >> 2 noticeable effects for -shared:
> >> >> >> >> >> >>
> >> >> >> >> >> >> * GOT-generating relocations referencing a protected data symbol no
> >> >> >> >> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
> >> >> >> >> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
> >> >> >> >> >> >>   confusing diagnostic below.
> >> >> >> >> >> >>
> >> >> >> >> >> >>     __attribute__((visibility("protected"))) void *foo() {
> >> >> >> >> >> >>       return (void *)foo;
> >> >> >> >> >> >>     }
> >> >> >> >> >> >>
> >> >> >> >> >> >>     // gcc -fpic -shared -fuse-ld=bfd
> >> >> >> >> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> >> >> >>
> >> >> >> >> >> >> The new behavior matches arm, aarch64 (commit
> >> >> >> >> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
> >> >> >> >> >> >> linkers: gold and ld.lld.
> >> >> >> >> >> >>
> >> >> >> >> >> >> Note: if some code tries to use direct access relocations to take the
> >> >> >> >> >> >> address of foo, the pointer equality will break, but the error should be
> >> >> >> >> >> >> reported on the executable link, not on the innocent shared object link.
> >> >> >> >> >> >> glibc 2.36 will give a warning at relocation resolving time.
> >> >> >> >> >> >
> >> >> >> >> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
> >> >> >> >> >> >-z  indirect-extern-access with -shared by default instead?
> >> >> >> >> >>
> >> >> >> >> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
> >> >> >> >> >> bfd/elf-properties.c:654 will create a
> >> >> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
> >> >> >> >> >> This will probably be unexpected (and check-ld will have 280+ failures).
> >> >> >> >> >
> >> >> >> >> >This is normal when the default behavior is changed.  You can pass
> >> >> >> >> >-z noindirect-extern-access to these testcases.
> >> >> >> >>
> >> >> >> >> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
> >> >> >> >> significant behavior change and may unnecessarily break user programs
> >> >> >> >> (glibc will report an error instead of a warning).
> >> >> >> >
> >> >> >> >If glibc reports an error, it is a real bug with unknown consequences
> >> >> >> >when the copy in the executable is out of sync with the protected
> >> >> >> >symbol in the shared library,
> >> >> >>
> >> >> >> Not necessary.
> >> >> >>
> >> >> >> In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
> >> >> >> 1 (copy relocations) and 2 (non-zero value of an undefined function
> >> >> >> symbol) on
> >> >> >> https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html
> >> >> >>
> >> >> >> 2 does not necessarily cause a problem. In many cases it doesn't as
> >> >> >> function pointer equality is not an invariant a program relies upon
> >> >> >> (at least, for many functions, the property is not used). My previous
> >> >> >> comment has mentioned two cases.
> >> >> >>
> >> >> >> 1 likely causes a problem, but technically the shared object can define
> >> >> >> a protected data symbol without accessing it..
> >> >> >
> >> >> >These are unknown consequences.   We don't know what the worst
> >> >> >cases are.
> >> >>
> >> >> They are, just like when a shared object is linked with -Bsymbolic.
> >> >
> >> >They have to deal with it since it is done on purpose.
> >> >
> >> >> This patch focuses on changing the x86 default to a sane value (matching
> >> >> aarch64/arm/powerpc64/riscv/etc) and enabling future removal of
> >> >> `extern_protected_data`.  If you want to switch to
> >> >> indirect-extern-access default for x86, while I think unnecessary, I will not object.
> >> >
> >> >extern_protected_data can be safely removed only when
> >> >direct access to external symbols are disallowed.   We can't
> >> >have both ways.
> >>
> >> Just define has_no_copy_on_protected to 1 to catch the usage at link
> >
> >This is the same as using -z indirect-extern-access on executable.
> >
> >> time.  ld's aarch64 port has such an error by default.  gold and ld.lld
> >> has such an error for a long time now.
> >>
> >> We don't need to worry about whether this stricter behavior breaks user
> >> programs.  As is, protected symbol using GCC+binutils provides no
> >> benefit.  Programs just avoid protected data symbols.
> >
> >Then there should be no problems with
> >GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
> >I'd like to disallow copy relocation on protected symbols at run-time
> >when there are unknown consequences.
>
> Enabling GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS for x86 by default
> has these effects:
>
> * 280+ check-ld tests will fail

They should be updated.

> * The GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note appears

It will disallow copy relocation on protected symbols at run-time.

>    redundant. It encodes an intention explicit but the intention is
>    in ld aarch64, gold (all ports), and lld (all ports) with no extra option.
>
> IMO, we should do these:
>
> * push this commit
> * treat elf_has_no_copy_on_protected as always true and remove all GNU_PROPERTY_NO_COPY_ON_PROTECTED
>
> Again, I understand that there is concern about protected data symbols
> in shared object.  But as is, nobody uses protected symbols in shared objects.
> My
>
>    // gcc -fpic -shared -fuse-ld=bfd
>    __attribute__((visibility("protected"))) void *foo() {
>      return (void *)foo;
>    }
>
> example indicates that protected future symbol is also broken.

To get protected symbol to work properly on x86-64, copy relocation on protected
symbols should be disallowed at run-time.

>
>
> >> >> But I'd note that we aren't really ready for the GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS default.
> >> >> One major issue: -fPIE is widely used nowadays and GCC>=5 has the PIE copy relocation "regression".
> >> >
> >> >-fno-PIE still has copy relocation.
> >>
> >> On a Linux distribution, -fno-PIE objects have largely vanished (due to PIE hardening).
> >> So for many shared objects protected symbols can start to be used.
> >>
> >> For the very few -fno-PIE exceptions, ask them to add an option. (This
> >> is similar to: distros keep pushing new security hardening options and
> >> some projects need to opt out them.)
> >>
> >> >> (My https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html
> >> >> will fix it for future GCC, but the patch seems to get stuck since 2021-05-11.)
> >> >>
> >> >> >> >> If the executable takes the address of a protected function defined in a
> >> >> >> >> shared object, it may or may not cause a pointer equality problem (the
> >> >> >> >> shared object may not take the address) and the problem (if exists) may or
> >> >> >> >> may not be a broken invariance to the program (it may not expect pointer
> >> >> >> >> equality).
> >> >> >> >>
> >> >> >> >> All of aarch64/arm/powerpc64/riscv (likely most except x86, but I
> >> >> >> >> haven't enumerated) consider a protected data symbol local in -shared
> >> >> >> >> links. x86 did so a while ago (before 2015?).  (For
> >> >> >> >> aarch64/arm/powerpc64/riscv, I wish that we never need
> >> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. The property will just
> >> >> >> >> waste some bytes in every shared object without carrying much
> >> >> >> >> information.)
> >> >> >> >>
> >> >> >> >> The 280+ failures in check-ld due to the default
> >> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS need to be considered as
> >> >> >> >> well.
> >> >> >> >>
> >> >> >> >> >> >> With this change, `#define elf_backend_extern_protected_data 1` is no
> >> >> >> >> >> >> longer effective.  Just remove it.
> >> >> >> >> >> >>
> >> >> >> >> >> >> Remove the test "Run protected-func-1 without PIE" since -fno-pic
> >> >> >> >> >> >> address taken operation in the executable doesn't work with protected
> >> >> >> >> >> >> symbol in a shared object by default.  Similarly, remove
> >> >> >> >> >> >> protected-data-1a and protected-data-1b.  protected-data-1b can be made
> >> >> >> >> >> >> working by removing HAVE_LD_PIE_COPYRELOC from GCC
> >> >> >> >> >> >> (https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
> >> >> >> >> >> >> ---
> >> >> >> >> >> >>  bfd/elf32-i386.c                      |  1 -
> >> >> >> >> >> >>  bfd/elf64-x86-64.c                    |  1 -
> >> >> >> >> >> >>  bfd/elfxx-x86.c                       |  2 +-
> >> >> >> >> >> >>  ld/testsuite/ld-i386/protected1.d     |  4 +++-
> >> >> >> >> >> >>  ld/testsuite/ld-i386/protected3.d     |  2 +-
> >> >> >> >> >> >>  ld/testsuite/ld-i386/protected6a.d    |  4 +++-
> >> >> >> >> >> >>  ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
> >> >> >> >> >> >>  ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
> >> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
> >> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected3.d   |  2 +-
> >> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
> >> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
> >> >> >> >> >> >>  ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
> >> >> >> >> >> >>  13 files changed, 24 insertions(+), 39 deletions(-)
> >> >> >> >> >> >>
> >> >> >> >> >> >> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> >> >> >> >> >> >> index e4106d9fd3b..c3c46795731 100644
> >> >> >> >> >> >> --- a/bfd/elf32-i386.c
> >> >> >> >> >> >> +++ b/bfd/elf32-i386.c
> >> >> >> >> >> >> @@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
> >> >> >> >> >> >>  #define elf_backend_got_header_size    12
> >> >> >> >> >> >>  #define elf_backend_plt_alignment      4
> >> >> >> >> >> >>  #define elf_backend_dtrel_excludes_plt 1
> >> >> >> >> >> >> -#define elf_backend_extern_protected_data 1
> >> >> >> >> >> >>  #define elf_backend_caches_rawsize     1
> >> >> >> >> >> >>  #define elf_backend_want_dynrelro      1
> >> >> >> >> >> >>
> >> >> >> >> >> >> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> >> >> >> >> >> >> index 6154a70bdd7..aaa5f1496b9 100644
> >> >> >> >> >> >> --- a/bfd/elf64-x86-64.c
> >> >> >> >> >> >> +++ b/bfd/elf64-x86-64.c
> >> >> >> >> >> >> @@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
> >> >> >> >> >> >>  #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
> >> >> >> >> >> >>  #define elf_backend_rela_normal                    1
> >> >> >> >> >> >>  #define elf_backend_plt_alignment          4
> >> >> >> >> >> >> -#define elf_backend_extern_protected_data   1
> >> >> >> >> >> >>  #define elf_backend_caches_rawsize         1
> >> >> >> >> >> >>  #define elf_backend_dtrel_excludes_plt     1
> >> >> >> >> >> >>  #define elf_backend_want_dynrelro          1
> >> >> >> >> >> >> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
> >> >> >> >> >> >> index acb2cc8528d..18f3d335458 100644
> >> >> >> >> >> >> --- a/bfd/elfxx-x86.c
> >> >> >> >> >> >> +++ b/bfd/elfxx-x86.c
> >> >> >> >> >> >> @@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
> >> >> >> >> >> >>       2. When building executable, there is no dynamic linker.  Or
> >> >> >> >> >> >>       3. or "-z nodynamic-undefined-weak" is used.
> >> >> >> >> >> >>     */
> >> >> >> >> >> >> -  if (SYMBOL_REFERENCES_LOCAL (info, h)
> >> >> >> >> >> >> +  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
> >> >> >> >> >> >>        || (h->root.type == bfd_link_hash_undefweak
> >> >> >> >> >> >>           && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
> >> >> >> >> >> >>               || (bfd_link_executable (info)
> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
> >> >> >> >> >> >> index a3cb5cef140..531645b8fe8 100644
> >> >> >> >> >> >> --- a/ld/testsuite/ld-i386/protected1.d
> >> >> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected1.d
> >> >> >> >> >> >> @@ -1,3 +1,5 @@
> >> >> >> >> >> >>  #as: --32
> >> >> >> >> >> >>  #ld: -shared -melf_i386
> >> >> >> >> >> >> -#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
> >> >> >> >> >> >> +#readelf: -rW
> >> >> >> >> >> >> +#...
> >> >> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
> >> >> >> >> >> >> index c3a6888d900..77367c4738f 100644
> >> >> >> >> >> >> --- a/ld/testsuite/ld-i386/protected3.d
> >> >> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected3.d
> >> >> >> >> >> >> @@ -8,7 +8,7 @@
> >> >> >> >> >> >>  Disassembly of section .text:
> >> >> >> >> >> >>
> >> >> >> >> >> >>  0+[a-f0-9]+ <bar>:
> >> >> >> >> >> >> -[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
> >> >> >> >> >> >> +[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
> >> >> >> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
> >> >> >> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
> >> >> >> >> >> >>  #pass
> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
> >> >> >> >> >> >> index 7dc350432f4..4d3873239f9 100644
> >> >> >> >> >> >> --- a/ld/testsuite/ld-i386/protected6a.d
> >> >> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected6a.d
> >> >> >> >> >> >> @@ -1,4 +1,6 @@
> >> >> >> >> >> >>  #source: protected6.s
> >> >> >> >> >> >>  #as: --32
> >> >> >> >> >> >>  #ld: -shared -melf_i386
> >> >> >> >> >> >> -#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
> >> >> >> >> >> >> +#readelf: -rW
> >> >> >> >> >> >> +#...
> >> >> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> >> >> >> >> index 130611ddf49..1f49b655f7d 100644
> >> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
> >> >> >> >> >> >> @@ -1,4 +1,6 @@
> >> >> >> >> >> >>  #source: pr24151a.s
> >> >> >> >> >> >>  #as: --x32
> >> >> >> >> >> >>  #ld: -shared -melf32_x86_64
> >> >> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> >> >> >> +#readelf: -rW
> >> >> >> >> >> >> +#...
> >> >> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> >> >> >> >> index 783b85a1a6f..6c48e383e01 100644
> >> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a.d
> >> >> >> >> >> >> @@ -1,3 +1,5 @@
> >> >> >> >> >> >>  #as: --64
> >> >> >> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> >> >> >> +#readelf: -rW
> >> >> >> >> >> >> +#...
> >> >> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
> >> >> >> >> >> >> index 783b85a1a6f..6c48e383e01 100644
> >> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected1.d
> >> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected1.d
> >> >> >> >> >> >> @@ -1,3 +1,5 @@
> >> >> >> >> >> >>  #as: --64
> >> >> >> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> >> >> >> >> +#readelf: -rW
> >> >> >> >> >> >> +#...
> >> >> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
> >> >> >> >> >> >> index 57950e4d6b6..ba63991582f 100644
> >> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected3.d
> >> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected3.d
> >> >> >> >> >> >> @@ -8,7 +8,7 @@
> >> >> >> >> >> >>  Disassembly of section .text:
> >> >> >> >> >> >>
> >> >> >> >> >> >>  0+[a-f0-9]+ <bar>:
> >> >> >> >> >> >> -[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> >> >> >> >> >> >> +[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
> >> >> >> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
> >> >> >> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
> >> >> >> >> >> >>  #pass
> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
> >> >> >> >> >> >> index 3a7963ffd2f..50d6430b577 100644
> >> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected6a.d
> >> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected6a.d
> >> >> >> >> >> >> @@ -1,4 +1,6 @@
> >> >> >> >> >> >>  #source: protected6.s
> >> >> >> >> >> >>  #as: --64
> >> >> >> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
> >> >> >> >> >> >> +#readelf: -rW
> >> >> >> >> >> >> +#...
> >> >> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
> >> >> >> >> >> >> index 3082084a7b8..3974246a2a8 100644
> >> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected7a.d
> >> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected7a.d
> >> >> >> >> >> >> @@ -1,4 +1,6 @@
> >> >> >> >> >> >>  #source: protected7.s
> >> >> >> >> >> >>  #as: --64
> >> >> >> >> >> >>  #ld: -shared -melf_x86_64
> >> >> >> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
> >> >> >> >> >> >> +#readelf: -rW
> >> >> >> >> >> >> +#...
> >> >> >> >> >> >> +There are no relocations in this file.
> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> >> >> >> >> index 5e5636bcebe..a096c0b9d0f 100644
> >> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
> >> >> >> >> >> >> @@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
> >> >> >> >> >> >>             "pr23997" \
> >> >> >> >> >> >>             "pass.out" \
> >> >> >> >> >> >>         ] \
> >> >> >> >> >> >> -       [list \
> >> >> >> >> >> >> -           "Run protected-func-1 without PIE" \
> >> >> >> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
> >> >> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> >> >> >> >> -           { protected-func-1b.c } \
> >> >> >> >> >> >> -           "protected-func-1a" \
> >> >> >> >> >> >> -           "pass.out" \
> >> >> >> >> >> >> -           "$NOPIE_CFLAGS" \
> >> >> >> >> >> >> -       ] \
> >> >> >> >> >> >>         [list \
> >> >> >> >> >> >>             "Run protected-func-1 with PIE" \
> >> >> >> >> >> >>             "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
> >> >> >> >> >> >> @@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
> >> >> >> >> >> >>             "pass.out" \
> >> >> >> >> >> >>             "-fPIE" \
> >> >> >> >> >> >>         ] \
> >> >> >> >> >> >> -       [list \
> >> >> >> >> >> >> -           "Run protected-data-1a without PIE" \
> >> >> >> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
> >> >> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> >> >> >> >> -           { protected-data-1b.c } \
> >> >> >> >> >> >> -           "protected-data-1a" \
> >> >> >> >> >> >> -           "pass.out" \
> >> >> >> >> >> >> -           "$NOPIE_CFLAGS" \
> >> >> >> >> >> >> -       ] \
> >> >> >> >> >> >> -       [list \
> >> >> >> >> >> >> -           "Run protected-data-1b with PIE" \
> >> >> >> >> >> >> -           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
> >> >> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
> >> >> >> >> >> >> -           { protected-data-1b.c } \
> >> >> >> >> >> >> -           "protected-data-1b" \
> >> >> >> >> >> >> -           "pass.out" \
> >> >> >> >> >> >> -           "-fPIE" \
> >> >> >> >> >> >> -       ] \
> >> >> >> >> >> >>         [list \
> >> >> >> >> >> >>             "Run protected-data-2a without PIE" \
> >> >> >> >> >> >>             "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
> >> >> >> >> >> >> --
> >> >> >> >> >> >> 2.37
> >> >> >> >> >> >>
> >> >> >> >> >> >
> >> >> >> >> >> >
> >> >> >> >> >> >--
> >> >> >> >> >> >H.J.
> >> >> >> >> >
> >> >> >> >> >
> >> >> >> >> >
> >> >> >> >> >--
> >> >> >> >> >H.J.
> >> >> >> >
> >> >> >> >
> >> >> >> >
> >> >> >> >--
> >> >> >> >H.J.
> >> >> >
> >> >> >
> >> >> >
> >> >> >--
> >> >> >H.J.
> >> >
> >> >
> >> >
> >> >--
> >> >H.J.
> >
> >
> >
> >--
> >H.J.



-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-28  3:51                         ` H.J. Lu
@ 2022-06-28  4:18                           ` Fangrui Song
  2022-07-19  1:44                             ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Fangrui Song @ 2022-06-28  4:18 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On 2022-06-27, H.J. Lu wrote:
>On Mon, Jun 27, 2022 at 8:44 PM Fangrui Song <i@maskray.me> wrote:
>>
>> On 2022-06-27, H.J. Lu wrote:
>> >On Mon, Jun 27, 2022 at 8:07 PM Fangrui Song <i@maskray.me> wrote:
>> >>
>> >> On 2022-06-27, H.J. Lu wrote:
>> >> >On Mon, Jun 27, 2022 at 11:46 AM Fangrui Song <i@maskray.me> wrote:
>> >> >>
>> >> >> On 2022-06-27, H.J. Lu wrote:
>> >> >> >On Mon, Jun 27, 2022 at 10:53 AM Fangrui Song <i@maskray.me> wrote:
>> >> >> >>
>> >> >> >> On 2022-06-27, H.J. Lu wrote:
>> >> >> >> >On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
>> >> >> >> >>
>> >> >> >> >> On 2022-06-27, H.J. Lu wrote:
>> >> >> >> >> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
>> >> >> >> >> >>
>> >> >> >> >> >> On 2022-06-26, H.J. Lu wrote:
>> >> >> >> >> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
>> >> >> >> >> >> >>
>> >> >> >> >> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
>> >> >> >> >> >> >> 2 noticeable effects for -shared:
>> >> >> >> >> >> >>
>> >> >> >> >> >> >> * GOT-generating relocations referencing a protected data symbol no
>> >> >> >> >> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
>> >> >> >> >> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
>> >> >> >> >> >> >>   confusing diagnostic below.
>> >> >> >> >> >> >>
>> >> >> >> >> >> >>     __attribute__((visibility("protected"))) void *foo() {
>> >> >> >> >> >> >>       return (void *)foo;
>> >> >> >> >> >> >>     }
>> >> >> >> >> >> >>
>> >> >> >> >> >> >>     // gcc -fpic -shared -fuse-ld=bfd
>> >> >> >> >> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> >> >> >>
>> >> >> >> >> >> >> The new behavior matches arm, aarch64 (commit
>> >> >> >> >> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
>> >> >> >> >> >> >> linkers: gold and ld.lld.
>> >> >> >> >> >> >>
>> >> >> >> >> >> >> Note: if some code tries to use direct access relocations to take the
>> >> >> >> >> >> >> address of foo, the pointer equality will break, but the error should be
>> >> >> >> >> >> >> reported on the executable link, not on the innocent shared object link.
>> >> >> >> >> >> >> glibc 2.36 will give a warning at relocation resolving time.
>> >> >> >> >> >> >
>> >> >> >> >> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
>> >> >> >> >> >> >-z  indirect-extern-access with -shared by default instead?
>> >> >> >> >> >>
>> >> >> >> >> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
>> >> >> >> >> >> bfd/elf-properties.c:654 will create a
>> >> >> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
>> >> >> >> >> >> This will probably be unexpected (and check-ld will have 280+ failures).
>> >> >> >> >> >
>> >> >> >> >> >This is normal when the default behavior is changed.  You can pass
>> >> >> >> >> >-z noindirect-extern-access to these testcases.
>> >> >> >> >>
>> >> >> >> >> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
>> >> >> >> >> significant behavior change and may unnecessarily break user programs
>> >> >> >> >> (glibc will report an error instead of a warning).
>> >> >> >> >
>> >> >> >> >If glibc reports an error, it is a real bug with unknown consequences
>> >> >> >> >when the copy in the executable is out of sync with the protected
>> >> >> >> >symbol in the shared library,
>> >> >> >>
>> >> >> >> Not necessary.
>> >> >> >>
>> >> >> >> In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
>> >> >> >> 1 (copy relocations) and 2 (non-zero value of an undefined function
>> >> >> >> symbol) on
>> >> >> >> https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html
>> >> >> >>
>> >> >> >> 2 does not necessarily cause a problem. In many cases it doesn't as
>> >> >> >> function pointer equality is not an invariant a program relies upon
>> >> >> >> (at least, for many functions, the property is not used). My previous
>> >> >> >> comment has mentioned two cases.
>> >> >> >>
>> >> >> >> 1 likely causes a problem, but technically the shared object can define
>> >> >> >> a protected data symbol without accessing it..
>> >> >> >
>> >> >> >These are unknown consequences.   We don't know what the worst
>> >> >> >cases are.
>> >> >>
>> >> >> They are, just like when a shared object is linked with -Bsymbolic.
>> >> >
>> >> >They have to deal with it since it is done on purpose.
>> >> >
>> >> >> This patch focuses on changing the x86 default to a sane value (matching
>> >> >> aarch64/arm/powerpc64/riscv/etc) and enabling future removal of
>> >> >> `extern_protected_data`.  If you want to switch to
>> >> >> indirect-extern-access default for x86, while I think unnecessary, I will not object.
>> >> >
>> >> >extern_protected_data can be safely removed only when
>> >> >direct access to external symbols are disallowed.   We can't
>> >> >have both ways.
>> >>
>> >> Just define has_no_copy_on_protected to 1 to catch the usage at link
>> >
>> >This is the same as using -z indirect-extern-access on executable.
>> >
>> >> time.  ld's aarch64 port has such an error by default.  gold and ld.lld
>> >> has such an error for a long time now.
>> >>
>> >> We don't need to worry about whether this stricter behavior breaks user
>> >> programs.  As is, protected symbol using GCC+binutils provides no
>> >> benefit.  Programs just avoid protected data symbols.
>> >
>> >Then there should be no problems with
>> >GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
>> >I'd like to disallow copy relocation on protected symbols at run-time
>> >when there are unknown consequences.
>>
>> Enabling GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS for x86 by default
>> has these effects:
>>
>> * 280+ check-ld tests will fail
>
>They should be updated.

That will be a huge effort and may not be so necessary. See below.

>> * The GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note appears
>
>It will disallow copy relocation on protected symbols at run-time.
>
>>    redundant. It encodes an intention explicit but the intention is
>>    in ld aarch64, gold (all ports), and lld (all ports) with no extra option.
>>
>> IMO, we should do these:
>>
>> * push this commit
>> * treat elf_has_no_copy_on_protected as always true and remove all GNU_PROPERTY_NO_COPY_ON_PROTECTED
>>
>> Again, I understand that there is concern about protected data symbols
>> in shared object.  But as is, nobody uses protected symbols in shared objects.
>> My
>>
>>    // gcc -fpic -shared -fuse-ld=bfd
>>    __attribute__((visibility("protected"))) void *foo() {
>>      return (void *)foo;
>>    }
>>
>> example indicates that protected future symbol is also broken.
>
>To get protected symbol to work properly on x86-64, copy relocation on protected
>symbols should be disallowed at run-time.

Yes that GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will change the
glibc warning to an error, but we don't need to hurry making the cases
an error.  Since protected symbols do not have performance benefits (in
gcc's many ports and GNU ld's x86 port), people avoid using it.  My
advise is to just let ld stop producing executables which will trigger
glibc warning/error (this has precedent in gold and ld.lld and FreeBSD's
adoption of ld.lld means that this goes actually very well).  Projects
will gradually fix their builds to enable indirect external access in
the rare case they encounter protected symbols in shared objects.  Then
in a few years, the glibc warning can naturally upgrade to an error,
with possibly a method (e.g. similar to LD_DYNAMIC_WEAK) to downgrade to
a warning.  Finally, remove the opt-out method.

With this scheme no GNU property is needed.

>>
>>
>> >> >> But I'd note that we aren't really ready for the GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS default.
>> >> >> One major issue: -fPIE is widely used nowadays and GCC>=5 has the PIE copy relocation "regression".
>> >> >
>> >> >-fno-PIE still has copy relocation.
>> >>
>> >> On a Linux distribution, -fno-PIE objects have largely vanished (due to PIE hardening).
>> >> So for many shared objects protected symbols can start to be used.
>> >>
>> >> For the very few -fno-PIE exceptions, ask them to add an option. (This
>> >> is similar to: distros keep pushing new security hardening options and
>> >> some projects need to opt out them.)
>> >>
>> >> >> (My https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html
>> >> >> will fix it for future GCC, but the patch seems to get stuck since 2021-05-11.)
>> >> >>
>> >> >> >> >> If the executable takes the address of a protected function defined in a
>> >> >> >> >> shared object, it may or may not cause a pointer equality problem (the
>> >> >> >> >> shared object may not take the address) and the problem (if exists) may or
>> >> >> >> >> may not be a broken invariance to the program (it may not expect pointer
>> >> >> >> >> equality).
>> >> >> >> >>
>> >> >> >> >> All of aarch64/arm/powerpc64/riscv (likely most except x86, but I
>> >> >> >> >> haven't enumerated) consider a protected data symbol local in -shared
>> >> >> >> >> links. x86 did so a while ago (before 2015?).  (For
>> >> >> >> >> aarch64/arm/powerpc64/riscv, I wish that we never need
>> >> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. The property will just
>> >> >> >> >> waste some bytes in every shared object without carrying much
>> >> >> >> >> information.)
>> >> >> >> >>
>> >> >> >> >> The 280+ failures in check-ld due to the default
>> >> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS need to be considered as
>> >> >> >> >> well.
>> >> >> >> >>
>> >> >> >> >> >> >> With this change, `#define elf_backend_extern_protected_data 1` is no
>> >> >> >> >> >> >> longer effective.  Just remove it.
>> >> >> >> >> >> >>
>> >> >> >> >> >> >> Remove the test "Run protected-func-1 without PIE" since -fno-pic
>> >> >> >> >> >> >> address taken operation in the executable doesn't work with protected
>> >> >> >> >> >> >> symbol in a shared object by default.  Similarly, remove
>> >> >> >> >> >> >> protected-data-1a and protected-data-1b.  protected-data-1b can be made
>> >> >> >> >> >> >> working by removing HAVE_LD_PIE_COPYRELOC from GCC
>> >> >> >> >> >> >> (https://sourceware.org/pipermail/gcc-patches/2022-June/596678.html).
>> >> >> >> >> >> >> ---
>> >> >> >> >> >> >>  bfd/elf32-i386.c                      |  1 -
>> >> >> >> >> >> >>  bfd/elf64-x86-64.c                    |  1 -
>> >> >> >> >> >> >>  bfd/elfxx-x86.c                       |  2 +-
>> >> >> >> >> >> >>  ld/testsuite/ld-i386/protected1.d     |  4 +++-
>> >> >> >> >> >> >>  ld/testsuite/ld-i386/protected3.d     |  2 +-
>> >> >> >> >> >> >>  ld/testsuite/ld-i386/protected6a.d    |  4 +++-
>> >> >> >> >> >> >>  ld/testsuite/ld-x86-64/pr24151a-x32.d |  4 +++-
>> >> >> >> >> >> >>  ld/testsuite/ld-x86-64/pr24151a.d     |  4 +++-
>> >> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected1.d   |  4 +++-
>> >> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected3.d   |  2 +-
>> >> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected6a.d  |  4 +++-
>> >> >> >> >> >> >>  ld/testsuite/ld-x86-64/protected7a.d  |  4 +++-
>> >> >> >> >> >> >>  ld/testsuite/ld-x86-64/x86-64.exp     | 27 ---------------------------
>> >> >> >> >> >> >>  13 files changed, 24 insertions(+), 39 deletions(-)
>> >> >> >> >> >> >>
>> >> >> >> >> >> >> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
>> >> >> >> >> >> >> index e4106d9fd3b..c3c46795731 100644
>> >> >> >> >> >> >> --- a/bfd/elf32-i386.c
>> >> >> >> >> >> >> +++ b/bfd/elf32-i386.c
>> >> >> >> >> >> >> @@ -4424,7 +4424,6 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
>> >> >> >> >> >> >>  #define elf_backend_got_header_size    12
>> >> >> >> >> >> >>  #define elf_backend_plt_alignment      4
>> >> >> >> >> >> >>  #define elf_backend_dtrel_excludes_plt 1
>> >> >> >> >> >> >> -#define elf_backend_extern_protected_data 1
>> >> >> >> >> >> >>  #define elf_backend_caches_rawsize     1
>> >> >> >> >> >> >>  #define elf_backend_want_dynrelro      1
>> >> >> >> >> >> >>
>> >> >> >> >> >> >> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
>> >> >> >> >> >> >> index 6154a70bdd7..aaa5f1496b9 100644
>> >> >> >> >> >> >> --- a/bfd/elf64-x86-64.c
>> >> >> >> >> >> >> +++ b/bfd/elf64-x86-64.c
>> >> >> >> >> >> >> @@ -5275,7 +5275,6 @@ elf_x86_64_special_sections[]=
>> >> >> >> >> >> >>  #define elf_backend_got_header_size        (GOT_ENTRY_SIZE*3)
>> >> >> >> >> >> >>  #define elf_backend_rela_normal                    1
>> >> >> >> >> >> >>  #define elf_backend_plt_alignment          4
>> >> >> >> >> >> >> -#define elf_backend_extern_protected_data   1
>> >> >> >> >> >> >>  #define elf_backend_caches_rawsize         1
>> >> >> >> >> >> >>  #define elf_backend_dtrel_excludes_plt     1
>> >> >> >> >> >> >>  #define elf_backend_want_dynrelro          1
>> >> >> >> >> >> >> diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
>> >> >> >> >> >> >> index acb2cc8528d..18f3d335458 100644
>> >> >> >> >> >> >> --- a/bfd/elfxx-x86.c
>> >> >> >> >> >> >> +++ b/bfd/elfxx-x86.c
>> >> >> >> >> >> >> @@ -3094,7 +3094,7 @@ _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
>> >> >> >> >> >> >>       2. When building executable, there is no dynamic linker.  Or
>> >> >> >> >> >> >>       3. or "-z nodynamic-undefined-weak" is used.
>> >> >> >> >> >> >>     */
>> >> >> >> >> >> >> -  if (SYMBOL_REFERENCES_LOCAL (info, h)
>> >> >> >> >> >> >> +  if (_bfd_elf_symbol_refs_local_p (h, info, 1)
>> >> >> >> >> >> >>        || (h->root.type == bfd_link_hash_undefweak
>> >> >> >> >> >> >>           && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
>> >> >> >> >> >> >>               || (bfd_link_executable (info)
>> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected1.d b/ld/testsuite/ld-i386/protected1.d
>> >> >> >> >> >> >> index a3cb5cef140..531645b8fe8 100644
>> >> >> >> >> >> >> --- a/ld/testsuite/ld-i386/protected1.d
>> >> >> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected1.d
>> >> >> >> >> >> >> @@ -1,3 +1,5 @@
>> >> >> >> >> >> >>  #as: --32
>> >> >> >> >> >> >>  #ld: -shared -melf_i386
>> >> >> >> >> >> >> -#error: .*relocation R_386_GOTOFF against protected function `foo' can not be used when making a shared object
>> >> >> >> >> >> >> +#readelf: -rW
>> >> >> >> >> >> >> +#...
>> >> >> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected3.d b/ld/testsuite/ld-i386/protected3.d
>> >> >> >> >> >> >> index c3a6888d900..77367c4738f 100644
>> >> >> >> >> >> >> --- a/ld/testsuite/ld-i386/protected3.d
>> >> >> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected3.d
>> >> >> >> >> >> >> @@ -8,7 +8,7 @@
>> >> >> >> >> >> >>  Disassembly of section .text:
>> >> >> >> >> >> >>
>> >> >> >> >> >> >>  0+[a-f0-9]+ <bar>:
>> >> >> >> >> >> >> -[      ]*[a-f0-9]+:    8b 81 [a-f0-9][a-f0-9] [a-f0-9][a-f0-9] ff ff           mov    -0x[a-f0-9]+\(%ecx\),%eax
>> >> >> >> >> >> >> +[      ]*[a-f0-9]+:    8d 81 00 00 00 00       lea    0x0\(%ecx\),%eax
>> >> >> >> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%eax\),%eax
>> >> >> >> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
>> >> >> >> >> >> >>  #pass
>> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-i386/protected6a.d b/ld/testsuite/ld-i386/protected6a.d
>> >> >> >> >> >> >> index 7dc350432f4..4d3873239f9 100644
>> >> >> >> >> >> >> --- a/ld/testsuite/ld-i386/protected6a.d
>> >> >> >> >> >> >> +++ b/ld/testsuite/ld-i386/protected6a.d
>> >> >> >> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >> >> >> >>  #source: protected6.s
>> >> >> >> >> >> >>  #as: --32
>> >> >> >> >> >> >>  #ld: -shared -melf_i386
>> >> >> >> >> >> >> -#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object
>> >> >> >> >> >> >> +#readelf: -rW
>> >> >> >> >> >> >> +#...
>> >> >> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a-x32.d b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> >> >> >> >> index 130611ddf49..1f49b655f7d 100644
>> >> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a-x32.d
>> >> >> >> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >> >> >> >>  #source: pr24151a.s
>> >> >> >> >> >> >>  #as: --x32
>> >> >> >> >> >> >>  #ld: -shared -melf32_x86_64
>> >> >> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> >> >> >> +#readelf: -rW
>> >> >> >> >> >> >> +#...
>> >> >> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/pr24151a.d b/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> >> >> >> >> index 783b85a1a6f..6c48e383e01 100644
>> >> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/pr24151a.d
>> >> >> >> >> >> >> @@ -1,3 +1,5 @@
>> >> >> >> >> >> >>  #as: --64
>> >> >> >> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> >> >> >> +#readelf: -rW
>> >> >> >> >> >> >> +#...
>> >> >> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected1.d b/ld/testsuite/ld-x86-64/protected1.d
>> >> >> >> >> >> >> index 783b85a1a6f..6c48e383e01 100644
>> >> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected1.d
>> >> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected1.d
>> >> >> >> >> >> >> @@ -1,3 +1,5 @@
>> >> >> >> >> >> >>  #as: --64
>> >> >> >> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> >> >> >> -#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> >> >> >> >> >> +#readelf: -rW
>> >> >> >> >> >> >> +#...
>> >> >> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected3.d b/ld/testsuite/ld-x86-64/protected3.d
>> >> >> >> >> >> >> index 57950e4d6b6..ba63991582f 100644
>> >> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected3.d
>> >> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected3.d
>> >> >> >> >> >> >> @@ -8,7 +8,7 @@
>> >> >> >> >> >> >>  Disassembly of section .text:
>> >> >> >> >> >> >>
>> >> >> >> >> >> >>  0+[a-f0-9]+ <bar>:
>> >> >> >> >> >> >> -[      ]*[a-f0-9]+:    48 8b 05 ([0-9a-f]{2} ){4} *    mov    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>> >> >> >> >> >> >> +[      ]*[a-f0-9]+:    48 8d 05 ([0-9a-f]{2} ){4} *    lea    0x[a-f0-9]+\(%rip\),%rax        # [a-f0-9]+ <.*>
>> >> >> >> >> >> >>  [      ]*[a-f0-9]+:    8b 00                   mov    \(%rax\),%eax
>> >> >> >> >> >> >>  [      ]*[a-f0-9]+:    c3                      ret
>> >> >> >> >> >> >>  #pass
>> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected6a.d b/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> >> >> >> >> index 3a7963ffd2f..50d6430b577 100644
>> >> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected6a.d
>> >> >> >> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >> >> >> >>  #source: protected6.s
>> >> >> >> >> >> >>  #as: --64
>> >> >> >> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object
>> >> >> >> >> >> >> +#readelf: -rW
>> >> >> >> >> >> >> +#...
>> >> >> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/protected7a.d b/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> >> >> >> >> index 3082084a7b8..3974246a2a8 100644
>> >> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/protected7a.d
>> >> >> >> >> >> >> @@ -1,4 +1,6 @@
>> >> >> >> >> >> >>  #source: protected7.s
>> >> >> >> >> >> >>  #as: --64
>> >> >> >> >> >> >>  #ld: -shared -melf_x86_64
>> >> >> >> >> >> >> -#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object
>> >> >> >> >> >> >> +#readelf: -rW
>> >> >> >> >> >> >> +#...
>> >> >> >> >> >> >> +There are no relocations in this file.
>> >> >> >> >> >> >> diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> >> >> >> >> index 5e5636bcebe..a096c0b9d0f 100644
>> >> >> >> >> >> >> --- a/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> >> >> >> >> +++ b/ld/testsuite/ld-x86-64/x86-64.exp
>> >> >> >> >> >> >> @@ -1832,15 +1832,6 @@ if { [isnative] && [check_compiler_available] } {
>> >> >> >> >> >> >>             "pr23997" \
>> >> >> >> >> >> >>             "pass.out" \
>> >> >> >> >> >> >>         ] \
>> >> >> >> >> >> >> -       [list \
>> >> >> >> >> >> >> -           "Run protected-func-1 without PIE" \
>> >> >> >> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-1.so" \
>> >> >> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> >> >> >> >> -           { protected-func-1b.c } \
>> >> >> >> >> >> >> -           "protected-func-1a" \
>> >> >> >> >> >> >> -           "pass.out" \
>> >> >> >> >> >> >> -           "$NOPIE_CFLAGS" \
>> >> >> >> >> >> >> -       ] \
>> >> >> >> >> >> >>         [list \
>> >> >> >> >> >> >>             "Run protected-func-1 with PIE" \
>> >> >> >> >> >> >>             "-Wl,--no-as-needed -pie tmpdir/libprotected-func-1.so" \
>> >> >> >> >> >> >> @@ -1904,24 +1895,6 @@ if { [isnative] && [check_compiler_available] } {
>> >> >> >> >> >> >>             "pass.out" \
>> >> >> >> >> >> >>             "-fPIE" \
>> >> >> >> >> >> >>         ] \
>> >> >> >> >> >> >> -       [list \
>> >> >> >> >> >> >> -           "Run protected-data-1a without PIE" \
>> >> >> >> >> >> >> -           "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
>> >> >> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> >> >> >> >> -           { protected-data-1b.c } \
>> >> >> >> >> >> >> -           "protected-data-1a" \
>> >> >> >> >> >> >> -           "pass.out" \
>> >> >> >> >> >> >> -           "$NOPIE_CFLAGS" \
>> >> >> >> >> >> >> -       ] \
>> >> >> >> >> >> >> -       [list \
>> >> >> >> >> >> >> -           "Run protected-data-1b with PIE" \
>> >> >> >> >> >> >> -           "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
>> >> >> >> >> >> >> -           "-Wa,-mx86-used-note=yes" \
>> >> >> >> >> >> >> -           { protected-data-1b.c } \
>> >> >> >> >> >> >> -           "protected-data-1b" \
>> >> >> >> >> >> >> -           "pass.out" \
>> >> >> >> >> >> >> -           "-fPIE" \
>> >> >> >> >> >> >> -       ] \
>> >> >> >> >> >> >>         [list \
>> >> >> >> >> >> >>             "Run protected-data-2a without PIE" \
>> >> >> >> >> >> >>             "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
>> >> >> >> >> >> >> --
>> >> >> >> >> >> >> 2.37
>> >> >> >> >> >> >>
>> >> >> >> >> >> >
>> >> >> >> >> >> >
>> >> >> >> >> >> >--
>> >> >> >> >> >> >H.J.
>> >> >> >> >> >
>> >> >> >> >> >
>> >> >> >> >> >
>> >> >> >> >> >--
>> >> >> >> >> >H.J.
>> >> >> >> >
>> >> >> >> >
>> >> >> >> >
>> >> >> >> >--
>> >> >> >> >H.J.
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> >--
>> >> >> >H.J.
>> >> >
>> >> >
>> >> >
>> >> >--
>> >> >H.J.
>> >
>> >
>> >
>> >--
>> >H.J.
>
>
>
>-- 
>H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-06-28  4:18                           ` Fangrui Song
@ 2022-07-19  1:44                             ` H.J. Lu
  2022-07-19  3:13                               ` Fangrui Song
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2022-07-19  1:44 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

On Mon, Jun 27, 2022 at 09:18:27PM -0700, Fangrui Song wrote:
> On 2022-06-27, H.J. Lu wrote:
> > On Mon, Jun 27, 2022 at 8:44 PM Fangrui Song <i@maskray.me> wrote:
> > > 
> > > On 2022-06-27, H.J. Lu wrote:
> > > >On Mon, Jun 27, 2022 at 8:07 PM Fangrui Song <i@maskray.me> wrote:
> > > >>
> > > >> On 2022-06-27, H.J. Lu wrote:
> > > >> >On Mon, Jun 27, 2022 at 11:46 AM Fangrui Song <i@maskray.me> wrote:
> > > >> >>
> > > >> >> On 2022-06-27, H.J. Lu wrote:
> > > >> >> >On Mon, Jun 27, 2022 at 10:53 AM Fangrui Song <i@maskray.me> wrote:
> > > >> >> >>
> > > >> >> >> On 2022-06-27, H.J. Lu wrote:
> > > >> >> >> >On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
> > > >> >> >> >>
> > > >> >> >> >> On 2022-06-27, H.J. Lu wrote:
> > > >> >> >> >> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
> > > >> >> >> >> >>
> > > >> >> >> >> >> On 2022-06-26, H.J. Lu wrote:
> > > >> >> >> >> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
> > > >> >> >> >> >> >>
> > > >> >> >> >> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
> > > >> >> >> >> >> >> 2 noticeable effects for -shared:
> > > >> >> >> >> >> >>
> > > >> >> >> >> >> >> * GOT-generating relocations referencing a protected data symbol no
> > > >> >> >> >> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
> > > >> >> >> >> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
> > > >> >> >> >> >> >>   confusing diagnostic below.
> > > >> >> >> >> >> >>
> > > >> >> >> >> >> >>     __attribute__((visibility("protected"))) void *foo() {
> > > >> >> >> >> >> >>       return (void *)foo;
> > > >> >> >> >> >> >>     }
> > > >> >> >> >> >> >>
> > > >> >> >> >> >> >>     // gcc -fpic -shared -fuse-ld=bfd
> > > >> >> >> >> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> > > >> >> >> >> >> >>
> > > >> >> >> >> >> >> The new behavior matches arm, aarch64 (commit
> > > >> >> >> >> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
> > > >> >> >> >> >> >> linkers: gold and ld.lld.
> > > >> >> >> >> >> >>
> > > >> >> >> >> >> >> Note: if some code tries to use direct access relocations to take the
> > > >> >> >> >> >> >> address of foo, the pointer equality will break, but the error should be
> > > >> >> >> >> >> >> reported on the executable link, not on the innocent shared object link.
> > > >> >> >> >> >> >> glibc 2.36 will give a warning at relocation resolving time.
> > > >> >> >> >> >> >
> > > >> >> >> >> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
> > > >> >> >> >> >> >-z  indirect-extern-access with -shared by default instead?
> > > >> >> >> >> >>
> > > >> >> >> >> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
> > > >> >> >> >> >> bfd/elf-properties.c:654 will create a
> > > >> >> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
> > > >> >> >> >> >> This will probably be unexpected (and check-ld will have 280+ failures).
> > > >> >> >> >> >
> > > >> >> >> >> >This is normal when the default behavior is changed.  You can pass
> > > >> >> >> >> >-z noindirect-extern-access to these testcases.
> > > >> >> >> >>
> > > >> >> >> >> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
> > > >> >> >> >> significant behavior change and may unnecessarily break user programs
> > > >> >> >> >> (glibc will report an error instead of a warning).
> > > >> >> >> >
> > > >> >> >> >If glibc reports an error, it is a real bug with unknown consequences
> > > >> >> >> >when the copy in the executable is out of sync with the protected
> > > >> >> >> >symbol in the shared library,
> > > >> >> >>
> > > >> >> >> Not necessary.
> > > >> >> >>
> > > >> >> >> In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
> > > >> >> >> 1 (copy relocations) and 2 (non-zero value of an undefined function
> > > >> >> >> symbol) on
> > > >> >> >> https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html
> > > >> >> >>
> > > >> >> >> 2 does not necessarily cause a problem. In many cases it doesn't as
> > > >> >> >> function pointer equality is not an invariant a program relies upon
> > > >> >> >> (at least, for many functions, the property is not used). My previous
> > > >> >> >> comment has mentioned two cases.
> > > >> >> >>
> > > >> >> >> 1 likely causes a problem, but technically the shared object can define
> > > >> >> >> a protected data symbol without accessing it..
> > > >> >> >
> > > >> >> >These are unknown consequences.   We don't know what the worst
> > > >> >> >cases are.
> > > >> >>
> > > >> >> They are, just like when a shared object is linked with -Bsymbolic.
> > > >> >
> > > >> >They have to deal with it since it is done on purpose.
> > > >> >
> > > >> >> This patch focuses on changing the x86 default to a sane value (matching
> > > >> >> aarch64/arm/powerpc64/riscv/etc) and enabling future removal of
> > > >> >> `extern_protected_data`.  If you want to switch to
> > > >> >> indirect-extern-access default for x86, while I think unnecessary, I will not object.
> > > >> >
> > > >> >extern_protected_data can be safely removed only when
> > > >> >direct access to external symbols are disallowed.   We can't
> > > >> >have both ways.
> > > >>
> > > >> Just define has_no_copy_on_protected to 1 to catch the usage at link
> > > >
> > > >This is the same as using -z indirect-extern-access on executable.
> > > >
> > > >> time.  ld's aarch64 port has such an error by default.  gold and ld.lld
> > > >> has such an error for a long time now.
> > > >>
> > > >> We don't need to worry about whether this stricter behavior breaks user
> > > >> programs.  As is, protected symbol using GCC+binutils provides no
> > > >> benefit.  Programs just avoid protected data symbols.
> > > >
> > > >Then there should be no problems with
> > > >GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
> > > >I'd like to disallow copy relocation on protected symbols at run-time
> > > >when there are unknown consequences.
> > > 
> > > Enabling GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS for x86 by default
> > > has these effects:
> > > 
> > > * 280+ check-ld tests will fail
> > 
> > They should be updated.
> 
> That will be a huge effort and may not be so necessary. See below.
> 
> > > * The GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note appears
> > 
> > It will disallow copy relocation on protected symbols at run-time.
> > 
> > >    redundant. It encodes an intention explicit but the intention is
> > >    in ld aarch64, gold (all ports), and lld (all ports) with no extra option.
> > > 
> > > IMO, we should do these:
> > > 
> > > * push this commit
> > > * treat elf_has_no_copy_on_protected as always true and remove all GNU_PROPERTY_NO_COPY_ON_PROTECTED
> > > 
> > > Again, I understand that there is concern about protected data symbols
> > > in shared object.  But as is, nobody uses protected symbols in shared objects.
> > > My
> > > 
> > >    // gcc -fpic -shared -fuse-ld=bfd
> > >    __attribute__((visibility("protected"))) void *foo() {
> > >      return (void *)foo;
> > >    }
> > > 
> > > example indicates that protected future symbol is also broken.
> > 
> > To get protected symbol to work properly on x86-64, copy relocation on protected
> > symbols should be disallowed at run-time.
> 
> Yes that GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will change the
> glibc warning to an error, but we don't need to hurry making the cases
> an error.  Since protected symbols do not have performance benefits (in
> gcc's many ports and GNU ld's x86 port), people avoid using it.  My
> advise is to just let ld stop producing executables which will trigger
> glibc warning/error (this has precedent in gold and ld.lld and FreeBSD's
> adoption of ld.lld means that this goes actually very well).  Projects
> will gradually fix their builds to enable indirect external access in
> the rare case they encounter protected symbols in shared objects.  Then
> in a few years, the glibc warning can naturally upgrade to an error,
> with possibly a method (e.g. similar to LD_DYNAMIC_WEAK) to downgrade to
> a warning.  Finally, remove the opt-out method.
> 
> With this scheme no GNU property is needed.

Then, linker should disallow copy relocation against protected symbols
and non-canonical reference to canonical protected functions.

Something like this.


H.J.
----
x86: Disallow invalid relocations against protected symbols

Since glibc 2.36 will issue warnings for copy relocation against
protected symbols and non-canonical reference to canonical protected
functions, change the linker to always disallow such relocations.

bfd/

	* elf32-i386.c (elf_i386_scan_relocs): Remove check for
	elf_has_indirect_extern_access.
	* elf64-x86-64.c (elf_x86_64_scan_relocs): Likewise.
	(elf_x86_64_relocate_section): Remove check for
	elf_has_no_copy_on_protected.
	* elfxx-x86.c (elf_x86_allocate_dynrelocs): Check for building
	executable instead of elf_has_no_copy_on_protected.
	(_bfd_x86_elf_adjust_dynamic_symbol): Disallow copy relocation
	against non-copyable protected symbol.
	* elfxx-x86.h (SYMBOL_NO_COPYRELOC): Remove check for
	elf_has_no_copy_on_protected.

ld/

	* testsuite/ld-i386/i386.exp: Expect linker error for PR ld/17709
	test.
	* testsuite/ld-i386/pr17709.rd: Removed.
	* testsuite/ld-i386/pr17709.err: New file.
	* testsuite/ld-x86-64/pr17709.rd: Removed.
	* testsuite/ld-x86-64/pr17709.err: New file.
	* testsuite/ld-x86-64/pr28875-func.err: Updated.
	* testsuite/ld-x86-64/x86-64.exp: Expect linker error for PR
	ld/17709 test.  Add tests for function pointer against protected
	function.
---
 bfd/elf32-i386.c                        |  3 +--
 bfd/elf64-x86-64.c                      | 10 +++-------
 bfd/elfxx-x86.c                         | 21 +++++++++++++++++++--
 bfd/elfxx-x86.h                         |  3 +--
 ld/testsuite/ld-i386/i386.exp           |  2 +-
 ld/testsuite/ld-i386/pr17709.err        |  2 ++
 ld/testsuite/ld-i386/pr17709.rd         |  4 ----
 ld/testsuite/ld-x86-64/pr17709.err      |  2 ++
 ld/testsuite/ld-x86-64/pr17709.rd       |  4 ----
 ld/testsuite/ld-x86-64/pr28875-func.err |  2 +-
 ld/testsuite/ld-x86-64/x86-64.exp       | 18 +++++++++++++++++-
 11 files changed, 47 insertions(+), 24 deletions(-)
 create mode 100644 ld/testsuite/ld-i386/pr17709.err
 delete mode 100644 ld/testsuite/ld-i386/pr17709.rd
 create mode 100644 ld/testsuite/ld-x86-64/pr17709.err
 delete mode 100644 ld/testsuite/ld-x86-64/pr17709.rd

diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 04a972e646d..cfb0085b245 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -1812,8 +1812,7 @@ elf_i386_scan_relocs (bfd *abfd,
 		      && h->type == STT_FUNC
 		      && eh->def_protected
 		      && !SYMBOL_DEFINED_NON_SHARED_P (h)
-		      && h->def_dynamic
-		      && elf_has_indirect_extern_access (h->root.u.def.section->owner))
+		      && h->def_dynamic)
 		    {
 		      /* Disallow non-canonical reference to canonical
 			 protected function.  */
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 3abc68a4127..62a9a22317a 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -2255,8 +2255,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
 		      && h->type == STT_FUNC
 		      && eh->def_protected
 		      && !SYMBOL_DEFINED_NON_SHARED_P (h)
-		      && h->def_dynamic
-		      && elf_has_indirect_extern_access (h->root.u.def.section->owner))
+		      && h->def_dynamic)
 		    {
 		      /* Disallow non-canonical reference to canonical
 			 protected function.  */
@@ -3156,8 +3155,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
 	       || (h != NULL
 		   && !h->root.linker_def
 		   && !h->root.ldscript_def
-		   && eh->def_protected
-		   && elf_has_no_copy_on_protected (h->root.u.def.section->owner)));
+		   && eh->def_protected));
 
 	  if ((input_section->flags & SEC_ALLOC) != 0
 	      && (input_section->flags & SEC_READONLY) != 0
@@ -4097,9 +4095,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
 	    {
 	    case R_X86_64_32S:
 	      sec = h->root.u.def.section;
-	      if ((info->nocopyreloc
-		   || (eh->def_protected
-		       && elf_has_no_copy_on_protected (h->root.u.def.section->owner)))
+	      if ((info->nocopyreloc || eh->def_protected)
 		  && !(h->root.u.def.section->flags & SEC_CODE))
 		return elf_x86_64_need_pic (info, input_bfd, input_section,
 					    h, NULL, NULL, howto);
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 18f3d335458..7fb972752b3 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -524,8 +524,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
     {
       asection *sreloc;
 
-      if (eh->def_protected
-	  && elf_has_no_copy_on_protected (h->root.u.def.section->owner))
+      if (eh->def_protected && bfd_link_executable (info))
 	{
 	  /* Disallow copy relocation against non-copyable protected
 	     symbol.  */
@@ -3041,6 +3040,24 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
     }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
+      if (eh->def_protected && bfd_link_executable (info))
+	for (p = h->dyn_relocs; p != NULL; p = p->next)
+	  {
+	    /* Disallow copy relocation against non-copyable protected
+	       symbol.  */
+	    s = p->sec->output_section;
+	    if (s != NULL && (s->flags & SEC_READONLY) != 0)
+	      {
+		info->callbacks->einfo
+		  /* xgettext:c-format */
+		  (_("%F%P: %pB: copy relocation against non-copyable "
+		     "protected symbol `%s' in %pB\n"),
+		   p->sec->owner, h->root.root.string,
+		   h->root.u.def.section->owner);
+		return false;
+	      }
+	  }
+
       srel->size += htab->sizeof_reloc;
       h->needs_copy = 1;
     }
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index 77fb1ad72bc..7d23893938c 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -135,12 +135,11 @@
 
 /* Should copy relocation be generated for a symbol.  Don't generate
    copy relocation against a protected symbol defined in a shared
-   object with GNU_PROPERTY_NO_COPY_ON_PROTECTED.  */
+   object.  */
 #define SYMBOL_NO_COPYRELOC(INFO, EH) \
   ((EH)->def_protected \
    && ((EH)->elf.root.type == bfd_link_hash_defined \
        || (EH)->elf.root.type == bfd_link_hash_defweak) \
-   && elf_has_no_copy_on_protected ((EH)->elf.root.u.def.section->owner) \
    && ((EH)->elf.root.u.def.section->owner->flags & DYNAMIC) != 0 \
    && ((EH)->elf.root.u.def.section->flags & SEC_CODE) == 0)
 
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index b4f7de49fd5..0ab9c001336 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -224,7 +224,7 @@ set i386tests {
      "--32 -mx86-used-note=yes" {pr17709a.s} {} "libpr17709.so"}
     {"PR ld/17709 (2)" "-melf_i386 tmpdir/libpr17709.so" ""
      "--32 -mx86-used-note=yes"
-     {pr17709b.s} {{readelf -r pr17709.rd}} "pr17709"}
+     {pr17709b.s} {{ld "pr17709.err"}} "pr17709"}
     {"Build pr19827a.o" "" ""
      "--32 -mx86-used-note=yes" { pr19827a.S }}
     {"Build pr19827b.so" "-melf_i386 -shared" ""
diff --git a/ld/testsuite/ld-i386/pr17709.err b/ld/testsuite/ld-i386/pr17709.err
new file mode 100644
index 00000000000..fa6a4bacce3
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr17709.err
@@ -0,0 +1,2 @@
+.*: tmpdir/pr17709b.o: copy relocation against non-copyable protected symbol `foo' in tmpdir/libpr17709.so
+#...
diff --git a/ld/testsuite/ld-i386/pr17709.rd b/ld/testsuite/ld-i386/pr17709.rd
deleted file mode 100644
index 8414784b736..00000000000
--- a/ld/testsuite/ld-i386/pr17709.rd
+++ /dev/null
@@ -1,4 +0,0 @@
-
-Relocation section '.rel\..*' at offset .* contains 1 entry:
- Offset     Info    Type            Sym\.Value  Sym\. Name
-[0-9a-f ]+R_386_COPY +[0-9a-f]+ +foo
diff --git a/ld/testsuite/ld-x86-64/pr17709.err b/ld/testsuite/ld-x86-64/pr17709.err
new file mode 100644
index 00000000000..fa6a4bacce3
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr17709.err
@@ -0,0 +1,2 @@
+.*: tmpdir/pr17709b.o: copy relocation against non-copyable protected symbol `foo' in tmpdir/libpr17709.so
+#...
diff --git a/ld/testsuite/ld-x86-64/pr17709.rd b/ld/testsuite/ld-x86-64/pr17709.rd
deleted file mode 100644
index beffd3cb34c..00000000000
--- a/ld/testsuite/ld-x86-64/pr17709.rd
+++ /dev/null
@@ -1,4 +0,0 @@
-
-Relocation section '.rela\..*' at offset .* contains 1 entry:
- +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
-[0-9a-f ]+R_X86_64_COPY+[0-9a-f ]+ +foo \+ 0
diff --git a/ld/testsuite/ld-x86-64/pr28875-func.err b/ld/testsuite/ld-x86-64/pr28875-func.err
index 64e961cb3d4..f6f4658deaf 100644
--- a/ld/testsuite/ld-x86-64/pr28875-func.err
+++ b/ld/testsuite/ld-x86-64/pr28875-func.err
@@ -1,2 +1,2 @@
-.*: tmpdir/protected-func-1b.o: non-canonical reference to canonical protected function `protected_func_1a' in tmpdir/libprotected-func-2b.so
+.*: tmpdir/protected-func-1b.o: non-canonical reference to canonical protected function `protected_func_1a' in tmpdir/libprotected-func-2..so
 #...
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index a096c0b9d0f..e6a834a2a61 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -177,7 +177,7 @@ set x86_64tests {
     {"PR ld/17709 (1)" "-melf_x86_64 -shared" ""
      "--64" {pr17709a.s} {} "libpr17709.so"}
     {"PR ld/17709 (2)" "-melf_x86_64 tmpdir/libpr17709.so" ""
-     "--64" {pr17709b.s} {{readelf -rW pr17709.rd}} "pr17709"}
+     "--64" {pr17709b.s} {{ld "pr17709.err"}} "pr17709"}
     {"Build pr19827a.o" "" ""
      "--64" { pr19827a.S }}
     {"Build pr19827b.so" "-melf_x86_64 -shared" ""
@@ -1383,6 +1383,22 @@ if { [isnative] && [check_compiler_available] } {
 	    {{error_output "pr28875-func.err"}} \
 	    "protected-func-2" \
 	] \
+	[list \
+	    "Build libprotected-func-2c.so" \
+	    "-shared" \
+	    "-fPIC -Wa,-mx86-used-note=yes" \
+	    { protected-func-2c.c } \
+	    {}  \
+	    "libprotected-func-2c.so" \
+	] \
+	[list \
+	    "Build protected-func-2a without PIE" \
+	    "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-2c.so" \
+	    "$NOPIE_CFLAGS -Wa,-mx86-used-note=yes" \
+	    { protected-func-1b.c } \
+	    {{error_output "pr28875-func.err"}} \
+	    "protected-func-2a" \
+	] \
 	[list \
 	    "Build libprotected-data-1a.so" \
 	    "-shared -z noindirect-extern-access" \
-- 
2.36.1


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-07-19  1:44                             ` H.J. Lu
@ 2022-07-19  3:13                               ` Fangrui Song
  2022-07-19  3:38                                 ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Fangrui Song @ 2022-07-19  3:13 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On 2022-07-18, H.J. Lu wrote:
>On Mon, Jun 27, 2022 at 09:18:27PM -0700, Fangrui Song wrote:
>> On 2022-06-27, H.J. Lu wrote:
>> > On Mon, Jun 27, 2022 at 8:44 PM Fangrui Song <i@maskray.me> wrote:
>> > >
>> > > On 2022-06-27, H.J. Lu wrote:
>> > > >On Mon, Jun 27, 2022 at 8:07 PM Fangrui Song <i@maskray.me> wrote:
>> > > >>
>> > > >> On 2022-06-27, H.J. Lu wrote:
>> > > >> >On Mon, Jun 27, 2022 at 11:46 AM Fangrui Song <i@maskray.me> wrote:
>> > > >> >>
>> > > >> >> On 2022-06-27, H.J. Lu wrote:
>> > > >> >> >On Mon, Jun 27, 2022 at 10:53 AM Fangrui Song <i@maskray.me> wrote:
>> > > >> >> >>
>> > > >> >> >> On 2022-06-27, H.J. Lu wrote:
>> > > >> >> >> >On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
>> > > >> >> >> >>
>> > > >> >> >> >> On 2022-06-27, H.J. Lu wrote:
>> > > >> >> >> >> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
>> > > >> >> >> >> >>
>> > > >> >> >> >> >> On 2022-06-26, H.J. Lu wrote:
>> > > >> >> >> >> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
>> > > >> >> >> >> >> >>
>> > > >> >> >> >> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
>> > > >> >> >> >> >> >> 2 noticeable effects for -shared:
>> > > >> >> >> >> >> >>
>> > > >> >> >> >> >> >> * GOT-generating relocations referencing a protected data symbol no
>> > > >> >> >> >> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
>> > > >> >> >> >> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
>> > > >> >> >> >> >> >>   confusing diagnostic below.
>> > > >> >> >> >> >> >>
>> > > >> >> >> >> >> >>     __attribute__((visibility("protected"))) void *foo() {
>> > > >> >> >> >> >> >>       return (void *)foo;
>> > > >> >> >> >> >> >>     }
>> > > >> >> >> >> >> >>
>> > > >> >> >> >> >> >>     // gcc -fpic -shared -fuse-ld=bfd
>> > > >> >> >> >> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> > > >> >> >> >> >> >>
>> > > >> >> >> >> >> >> The new behavior matches arm, aarch64 (commit
>> > > >> >> >> >> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
>> > > >> >> >> >> >> >> linkers: gold and ld.lld.
>> > > >> >> >> >> >> >>
>> > > >> >> >> >> >> >> Note: if some code tries to use direct access relocations to take the
>> > > >> >> >> >> >> >> address of foo, the pointer equality will break, but the error should be
>> > > >> >> >> >> >> >> reported on the executable link, not on the innocent shared object link.
>> > > >> >> >> >> >> >> glibc 2.36 will give a warning at relocation resolving time.
>> > > >> >> >> >> >> >
>> > > >> >> >> >> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
>> > > >> >> >> >> >> >-z  indirect-extern-access with -shared by default instead?
>> > > >> >> >> >> >>
>> > > >> >> >> >> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
>> > > >> >> >> >> >> bfd/elf-properties.c:654 will create a
>> > > >> >> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
>> > > >> >> >> >> >> This will probably be unexpected (and check-ld will have 280+ failures).
>> > > >> >> >> >> >
>> > > >> >> >> >> >This is normal when the default behavior is changed.  You can pass
>> > > >> >> >> >> >-z noindirect-extern-access to these testcases.
>> > > >> >> >> >>
>> > > >> >> >> >> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
>> > > >> >> >> >> significant behavior change and may unnecessarily break user programs
>> > > >> >> >> >> (glibc will report an error instead of a warning).
>> > > >> >> >> >
>> > > >> >> >> >If glibc reports an error, it is a real bug with unknown consequences
>> > > >> >> >> >when the copy in the executable is out of sync with the protected
>> > > >> >> >> >symbol in the shared library,
>> > > >> >> >>
>> > > >> >> >> Not necessary.
>> > > >> >> >>
>> > > >> >> >> In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
>> > > >> >> >> 1 (copy relocations) and 2 (non-zero value of an undefined function
>> > > >> >> >> symbol) on
>> > > >> >> >> https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html
>> > > >> >> >>
>> > > >> >> >> 2 does not necessarily cause a problem. In many cases it doesn't as
>> > > >> >> >> function pointer equality is not an invariant a program relies upon
>> > > >> >> >> (at least, for many functions, the property is not used). My previous
>> > > >> >> >> comment has mentioned two cases.
>> > > >> >> >>
>> > > >> >> >> 1 likely causes a problem, but technically the shared object can define
>> > > >> >> >> a protected data symbol without accessing it..
>> > > >> >> >
>> > > >> >> >These are unknown consequences.   We don't know what the worst
>> > > >> >> >cases are.
>> > > >> >>
>> > > >> >> They are, just like when a shared object is linked with -Bsymbolic.
>> > > >> >
>> > > >> >They have to deal with it since it is done on purpose.
>> > > >> >
>> > > >> >> This patch focuses on changing the x86 default to a sane value (matching
>> > > >> >> aarch64/arm/powerpc64/riscv/etc) and enabling future removal of
>> > > >> >> `extern_protected_data`.  If you want to switch to
>> > > >> >> indirect-extern-access default for x86, while I think unnecessary, I will not object.
>> > > >> >
>> > > >> >extern_protected_data can be safely removed only when
>> > > >> >direct access to external symbols are disallowed.   We can't
>> > > >> >have both ways.
>> > > >>
>> > > >> Just define has_no_copy_on_protected to 1 to catch the usage at link
>> > > >
>> > > >This is the same as using -z indirect-extern-access on executable.
>> > > >
>> > > >> time.  ld's aarch64 port has such an error by default.  gold and ld.lld
>> > > >> has such an error for a long time now.
>> > > >>
>> > > >> We don't need to worry about whether this stricter behavior breaks user
>> > > >> programs.  As is, protected symbol using GCC+binutils provides no
>> > > >> benefit.  Programs just avoid protected data symbols.
>> > > >
>> > > >Then there should be no problems with
>> > > >GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
>> > > >I'd like to disallow copy relocation on protected symbols at run-time
>> > > >when there are unknown consequences.
>> > >
>> > > Enabling GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS for x86 by default
>> > > has these effects:
>> > >
>> > > * 280+ check-ld tests will fail
>> >
>> > They should be updated.
>>
>> That will be a huge effort and may not be so necessary. See below.
>>
>> > > * The GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note appears
>> >
>> > It will disallow copy relocation on protected symbols at run-time.
>> >
>> > >    redundant. It encodes an intention explicit but the intention is
>> > >    in ld aarch64, gold (all ports), and lld (all ports) with no extra option.
>> > >
>> > > IMO, we should do these:
>> > >
>> > > * push this commit
>> > > * treat elf_has_no_copy_on_protected as always true and remove all GNU_PROPERTY_NO_COPY_ON_PROTECTED
>> > >
>> > > Again, I understand that there is concern about protected data symbols
>> > > in shared object.  But as is, nobody uses protected symbols in shared objects.
>> > > My
>> > >
>> > >    // gcc -fpic -shared -fuse-ld=bfd
>> > >    __attribute__((visibility("protected"))) void *foo() {
>> > >      return (void *)foo;
>> > >    }
>> > >
>> > > example indicates that protected future symbol is also broken.
>> >
>> > To get protected symbol to work properly on x86-64, copy relocation on protected
>> > symbols should be disallowed at run-time.
>>
>> Yes that GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will change the
>> glibc warning to an error, but we don't need to hurry making the cases
>> an error.  Since protected symbols do not have performance benefits (in
>> gcc's many ports and GNU ld's x86 port), people avoid using it.  My
>> advise is to just let ld stop producing executables which will trigger
>> glibc warning/error (this has precedent in gold and ld.lld and FreeBSD's
>> adoption of ld.lld means that this goes actually very well).  Projects
>> will gradually fix their builds to enable indirect external access in
>> the rare case they encounter protected symbols in shared objects.  Then
>> in a few years, the glibc warning can naturally upgrade to an error,
>> with possibly a method (e.g. similar to LD_DYNAMIC_WEAK) to downgrade to
>> a warning.  Finally, remove the opt-out method.
>>
>> With this scheme no GNU property is needed.
>
>Then, linker should disallow copy relocation against protected symbols
>and non-canonical reference to canonical protected functions.
>
>Something like this.
>
>
>H.J.
>----
>x86: Disallow invalid relocations against protected symbols
>
>Since glibc 2.36 will issue warnings for copy relocation against
>protected symbols and non-canonical reference to canonical protected
>functions, change the linker to always disallow such relocations.

Thanks.  When reporting relocation diagnostics, making the condition
stricter by removing elf_has_indirect_extern_access is the right
direction.


Your patch alone isn't sufficient to make -fpic -shared below work:

__attribute__((visibility("protected"))) void *foo() {
   return (void *)foo;
}


>bfd/
>
>	* elf32-i386.c (elf_i386_scan_relocs): Remove check for
>	elf_has_indirect_extern_access.
>	* elf64-x86-64.c (elf_x86_64_scan_relocs): Likewise.
>	(elf_x86_64_relocate_section): Remove check for
>	elf_has_no_copy_on_protected.
>	* elfxx-x86.c (elf_x86_allocate_dynrelocs): Check for building
>	executable instead of elf_has_no_copy_on_protected.
>	(_bfd_x86_elf_adjust_dynamic_symbol): Disallow copy relocation
>	against non-copyable protected symbol.
>	* elfxx-x86.h (SYMBOL_NO_COPYRELOC): Remove check for
>	elf_has_no_copy_on_protected.
>
>ld/
>
>	* testsuite/ld-i386/i386.exp: Expect linker error for PR ld/17709
>	test.
>	* testsuite/ld-i386/pr17709.rd: Removed.
>	* testsuite/ld-i386/pr17709.err: New file.
>	* testsuite/ld-x86-64/pr17709.rd: Removed.
>	* testsuite/ld-x86-64/pr17709.err: New file.
>	* testsuite/ld-x86-64/pr28875-func.err: Updated.
>	* testsuite/ld-x86-64/x86-64.exp: Expect linker error for PR
>	ld/17709 test.  Add tests for function pointer against protected
>	function.
>---
> bfd/elf32-i386.c                        |  3 +--
> bfd/elf64-x86-64.c                      | 10 +++-------
> bfd/elfxx-x86.c                         | 21 +++++++++++++++++++--
> bfd/elfxx-x86.h                         |  3 +--
> ld/testsuite/ld-i386/i386.exp           |  2 +-
> ld/testsuite/ld-i386/pr17709.err        |  2 ++
> ld/testsuite/ld-i386/pr17709.rd         |  4 ----
> ld/testsuite/ld-x86-64/pr17709.err      |  2 ++
> ld/testsuite/ld-x86-64/pr17709.rd       |  4 ----
> ld/testsuite/ld-x86-64/pr28875-func.err |  2 +-
> ld/testsuite/ld-x86-64/x86-64.exp       | 18 +++++++++++++++++-
> 11 files changed, 47 insertions(+), 24 deletions(-)
> create mode 100644 ld/testsuite/ld-i386/pr17709.err
> delete mode 100644 ld/testsuite/ld-i386/pr17709.rd
> create mode 100644 ld/testsuite/ld-x86-64/pr17709.err
> delete mode 100644 ld/testsuite/ld-x86-64/pr17709.rd
>
>diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
>index 04a972e646d..cfb0085b245 100644
>--- a/bfd/elf32-i386.c
>+++ b/bfd/elf32-i386.c
>@@ -1812,8 +1812,7 @@ elf_i386_scan_relocs (bfd *abfd,
> 		      && h->type == STT_FUNC
> 		      && eh->def_protected
> 		      && !SYMBOL_DEFINED_NON_SHARED_P (h)
>-		      && h->def_dynamic
>-		      && elf_has_indirect_extern_access (h->root.u.def.section->owner))
>+		      && h->def_dynamic)
> 		    {
> 		      /* Disallow non-canonical reference to canonical
> 			 protected function.  */
>diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
>index 3abc68a4127..62a9a22317a 100644
>--- a/bfd/elf64-x86-64.c
>+++ b/bfd/elf64-x86-64.c
>@@ -2255,8 +2255,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
> 		      && h->type == STT_FUNC
> 		      && eh->def_protected
> 		      && !SYMBOL_DEFINED_NON_SHARED_P (h)
>-		      && h->def_dynamic
>-		      && elf_has_indirect_extern_access (h->root.u.def.section->owner))
>+		      && h->def_dynamic)
> 		    {
> 		      /* Disallow non-canonical reference to canonical
> 			 protected function.  */
>@@ -3156,8 +3155,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> 	       || (h != NULL
> 		   && !h->root.linker_def
> 		   && !h->root.ldscript_def
>-		   && eh->def_protected
>-		   && elf_has_no_copy_on_protected (h->root.u.def.section->owner)));
>+		   && eh->def_protected));
>
> 	  if ((input_section->flags & SEC_ALLOC) != 0
> 	      && (input_section->flags & SEC_READONLY) != 0
>@@ -4097,9 +4095,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> 	    {
> 	    case R_X86_64_32S:
> 	      sec = h->root.u.def.section;
>-	      if ((info->nocopyreloc
>-		   || (eh->def_protected
>-		       && elf_has_no_copy_on_protected (h->root.u.def.section->owner)))
>+	      if ((info->nocopyreloc || eh->def_protected)
> 		  && !(h->root.u.def.section->flags & SEC_CODE))
> 		return elf_x86_64_need_pic (info, input_bfd, input_section,
> 					    h, NULL, NULL, howto);
>diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
>index 18f3d335458..7fb972752b3 100644
>--- a/bfd/elfxx-x86.c
>+++ b/bfd/elfxx-x86.c
>@@ -524,8 +524,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
>     {
>       asection *sreloc;
>
>-      if (eh->def_protected
>-	  && elf_has_no_copy_on_protected (h->root.u.def.section->owner))
>+      if (eh->def_protected && bfd_link_executable (info))
> 	{
> 	  /* Disallow copy relocation against non-copyable protected
> 	     symbol.  */
>@@ -3041,6 +3040,24 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
>     }
>   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
>     {
>+      if (eh->def_protected && bfd_link_executable (info))
>+	for (p = h->dyn_relocs; p != NULL; p = p->next)
>+	  {
>+	    /* Disallow copy relocation against non-copyable protected
>+	       symbol.  */
>+	    s = p->sec->output_section;
>+	    if (s != NULL && (s->flags & SEC_READONLY) != 0)
>+	      {
>+		info->callbacks->einfo
>+		  /* xgettext:c-format */
>+		  (_("%F%P: %pB: copy relocation against non-copyable "
>+		     "protected symbol `%s' in %pB\n"),
>+		   p->sec->owner, h->root.root.string,
>+		   h->root.u.def.section->owner);
>+		return false;
>+	      }
>+	  }
>+
>       srel->size += htab->sizeof_reloc;
>       h->needs_copy = 1;
>     }
>diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
>index 77fb1ad72bc..7d23893938c 100644
>--- a/bfd/elfxx-x86.h
>+++ b/bfd/elfxx-x86.h
>@@ -135,12 +135,11 @@
>
> /* Should copy relocation be generated for a symbol.  Don't generate
>    copy relocation against a protected symbol defined in a shared
>-   object with GNU_PROPERTY_NO_COPY_ON_PROTECTED.  */
>+   object.  */
> #define SYMBOL_NO_COPYRELOC(INFO, EH) \
>   ((EH)->def_protected \
>    && ((EH)->elf.root.type == bfd_link_hash_defined \
>        || (EH)->elf.root.type == bfd_link_hash_defweak) \
>-   && elf_has_no_copy_on_protected ((EH)->elf.root.u.def.section->owner) \
>    && ((EH)->elf.root.u.def.section->owner->flags & DYNAMIC) != 0 \
>    && ((EH)->elf.root.u.def.section->flags & SEC_CODE) == 0)
>
>diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
>index b4f7de49fd5..0ab9c001336 100644
>--- a/ld/testsuite/ld-i386/i386.exp
>+++ b/ld/testsuite/ld-i386/i386.exp
>@@ -224,7 +224,7 @@ set i386tests {
>      "--32 -mx86-used-note=yes" {pr17709a.s} {} "libpr17709.so"}
>     {"PR ld/17709 (2)" "-melf_i386 tmpdir/libpr17709.so" ""
>      "--32 -mx86-used-note=yes"
>-     {pr17709b.s} {{readelf -r pr17709.rd}} "pr17709"}
>+     {pr17709b.s} {{ld "pr17709.err"}} "pr17709"}
>     {"Build pr19827a.o" "" ""
>      "--32 -mx86-used-note=yes" { pr19827a.S }}
>     {"Build pr19827b.so" "-melf_i386 -shared" ""
>diff --git a/ld/testsuite/ld-i386/pr17709.err b/ld/testsuite/ld-i386/pr17709.err
>new file mode 100644
>index 00000000000..fa6a4bacce3
>--- /dev/null
>+++ b/ld/testsuite/ld-i386/pr17709.err
>@@ -0,0 +1,2 @@
>+.*: tmpdir/pr17709b.o: copy relocation against non-copyable protected symbol `foo' in tmpdir/libpr17709.so
>+#...
>diff --git a/ld/testsuite/ld-i386/pr17709.rd b/ld/testsuite/ld-i386/pr17709.rd
>deleted file mode 100644
>index 8414784b736..00000000000
>--- a/ld/testsuite/ld-i386/pr17709.rd
>+++ /dev/null
>@@ -1,4 +0,0 @@
>-
>-Relocation section '.rel\..*' at offset .* contains 1 entry:
>- Offset     Info    Type            Sym\.Value  Sym\. Name
>-[0-9a-f ]+R_386_COPY +[0-9a-f]+ +foo
>diff --git a/ld/testsuite/ld-x86-64/pr17709.err b/ld/testsuite/ld-x86-64/pr17709.err
>new file mode 100644
>index 00000000000..fa6a4bacce3
>--- /dev/null
>+++ b/ld/testsuite/ld-x86-64/pr17709.err
>@@ -0,0 +1,2 @@
>+.*: tmpdir/pr17709b.o: copy relocation against non-copyable protected symbol `foo' in tmpdir/libpr17709.so
>+#...
>diff --git a/ld/testsuite/ld-x86-64/pr17709.rd b/ld/testsuite/ld-x86-64/pr17709.rd
>deleted file mode 100644
>index beffd3cb34c..00000000000
>--- a/ld/testsuite/ld-x86-64/pr17709.rd
>+++ /dev/null
>@@ -1,4 +0,0 @@
>-
>-Relocation section '.rela\..*' at offset .* contains 1 entry:
>- +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
>-[0-9a-f ]+R_X86_64_COPY+[0-9a-f ]+ +foo \+ 0
>diff --git a/ld/testsuite/ld-x86-64/pr28875-func.err b/ld/testsuite/ld-x86-64/pr28875-func.err
>index 64e961cb3d4..f6f4658deaf 100644
>--- a/ld/testsuite/ld-x86-64/pr28875-func.err
>+++ b/ld/testsuite/ld-x86-64/pr28875-func.err
>@@ -1,2 +1,2 @@
>-.*: tmpdir/protected-func-1b.o: non-canonical reference to canonical protected function `protected_func_1a' in tmpdir/libprotected-func-2b.so
>+.*: tmpdir/protected-func-1b.o: non-canonical reference to canonical protected function `protected_func_1a' in tmpdir/libprotected-func-2..so
> #...
>diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
>index a096c0b9d0f..e6a834a2a61 100644
>--- a/ld/testsuite/ld-x86-64/x86-64.exp
>+++ b/ld/testsuite/ld-x86-64/x86-64.exp
>@@ -177,7 +177,7 @@ set x86_64tests {
>     {"PR ld/17709 (1)" "-melf_x86_64 -shared" ""
>      "--64" {pr17709a.s} {} "libpr17709.so"}
>     {"PR ld/17709 (2)" "-melf_x86_64 tmpdir/libpr17709.so" ""
>-     "--64" {pr17709b.s} {{readelf -rW pr17709.rd}} "pr17709"}
>+     "--64" {pr17709b.s} {{ld "pr17709.err"}} "pr17709"}
>     {"Build pr19827a.o" "" ""
>      "--64" { pr19827a.S }}
>     {"Build pr19827b.so" "-melf_x86_64 -shared" ""
>@@ -1383,6 +1383,22 @@ if { [isnative] && [check_compiler_available] } {
> 	    {{error_output "pr28875-func.err"}} \
> 	    "protected-func-2" \
> 	] \
>+	[list \
>+	    "Build libprotected-func-2c.so" \
>+	    "-shared" \
>+	    "-fPIC -Wa,-mx86-used-note=yes" \
>+	    { protected-func-2c.c } \
>+	    {}  \
>+	    "libprotected-func-2c.so" \
>+	] \
>+	[list \
>+	    "Build protected-func-2a without PIE" \
>+	    "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-2c.so" \
>+	    "$NOPIE_CFLAGS -Wa,-mx86-used-note=yes" \
>+	    { protected-func-1b.c } \
>+	    {{error_output "pr28875-func.err"}} \
>+	    "protected-func-2a" \
>+	] \
> 	[list \
> 	    "Build libprotected-data-1a.so" \
> 	    "-shared -z noindirect-extern-access" \
>-- 
>2.36.1
>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-07-19  3:13                               ` Fangrui Song
@ 2022-07-19  3:38                                 ` H.J. Lu
  2022-07-19  4:02                                   ` Fangrui Song
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2022-07-19  3:38 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

On Mon, Jul 18, 2022 at 8:13 PM Fangrui Song <i@maskray.me> wrote:
>
> On 2022-07-18, H.J. Lu wrote:
> >On Mon, Jun 27, 2022 at 09:18:27PM -0700, Fangrui Song wrote:
> >> On 2022-06-27, H.J. Lu wrote:
> >> > On Mon, Jun 27, 2022 at 8:44 PM Fangrui Song <i@maskray.me> wrote:
> >> > >
> >> > > On 2022-06-27, H.J. Lu wrote:
> >> > > >On Mon, Jun 27, 2022 at 8:07 PM Fangrui Song <i@maskray.me> wrote:
> >> > > >>
> >> > > >> On 2022-06-27, H.J. Lu wrote:
> >> > > >> >On Mon, Jun 27, 2022 at 11:46 AM Fangrui Song <i@maskray.me> wrote:
> >> > > >> >>
> >> > > >> >> On 2022-06-27, H.J. Lu wrote:
> >> > > >> >> >On Mon, Jun 27, 2022 at 10:53 AM Fangrui Song <i@maskray.me> wrote:
> >> > > >> >> >>
> >> > > >> >> >> On 2022-06-27, H.J. Lu wrote:
> >> > > >> >> >> >On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
> >> > > >> >> >> >>
> >> > > >> >> >> >> On 2022-06-27, H.J. Lu wrote:
> >> > > >> >> >> >> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
> >> > > >> >> >> >> >>
> >> > > >> >> >> >> >> On 2022-06-26, H.J. Lu wrote:
> >> > > >> >> >> >> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
> >> > > >> >> >> >> >> >>
> >> > > >> >> >> >> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
> >> > > >> >> >> >> >> >> 2 noticeable effects for -shared:
> >> > > >> >> >> >> >> >>
> >> > > >> >> >> >> >> >> * GOT-generating relocations referencing a protected data symbol no
> >> > > >> >> >> >> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
> >> > > >> >> >> >> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
> >> > > >> >> >> >> >> >>   confusing diagnostic below.
> >> > > >> >> >> >> >> >>
> >> > > >> >> >> >> >> >>     __attribute__((visibility("protected"))) void *foo() {
> >> > > >> >> >> >> >> >>       return (void *)foo;
> >> > > >> >> >> >> >> >>     }
> >> > > >> >> >> >> >> >>
> >> > > >> >> >> >> >> >>     // gcc -fpic -shared -fuse-ld=bfd
> >> > > >> >> >> >> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> > > >> >> >> >> >> >>
> >> > > >> >> >> >> >> >> The new behavior matches arm, aarch64 (commit
> >> > > >> >> >> >> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
> >> > > >> >> >> >> >> >> linkers: gold and ld.lld.
> >> > > >> >> >> >> >> >>
> >> > > >> >> >> >> >> >> Note: if some code tries to use direct access relocations to take the
> >> > > >> >> >> >> >> >> address of foo, the pointer equality will break, but the error should be
> >> > > >> >> >> >> >> >> reported on the executable link, not on the innocent shared object link.
> >> > > >> >> >> >> >> >> glibc 2.36 will give a warning at relocation resolving time.
> >> > > >> >> >> >> >> >
> >> > > >> >> >> >> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
> >> > > >> >> >> >> >> >-z  indirect-extern-access with -shared by default instead?
> >> > > >> >> >> >> >>
> >> > > >> >> >> >> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
> >> > > >> >> >> >> >> bfd/elf-properties.c:654 will create a
> >> > > >> >> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
> >> > > >> >> >> >> >> This will probably be unexpected (and check-ld will have 280+ failures).
> >> > > >> >> >> >> >
> >> > > >> >> >> >> >This is normal when the default behavior is changed.  You can pass
> >> > > >> >> >> >> >-z noindirect-extern-access to these testcases.
> >> > > >> >> >> >>
> >> > > >> >> >> >> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
> >> > > >> >> >> >> significant behavior change and may unnecessarily break user programs
> >> > > >> >> >> >> (glibc will report an error instead of a warning).
> >> > > >> >> >> >
> >> > > >> >> >> >If glibc reports an error, it is a real bug with unknown consequences
> >> > > >> >> >> >when the copy in the executable is out of sync with the protected
> >> > > >> >> >> >symbol in the shared library,
> >> > > >> >> >>
> >> > > >> >> >> Not necessary.
> >> > > >> >> >>
> >> > > >> >> >> In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
> >> > > >> >> >> 1 (copy relocations) and 2 (non-zero value of an undefined function
> >> > > >> >> >> symbol) on
> >> > > >> >> >> https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html
> >> > > >> >> >>
> >> > > >> >> >> 2 does not necessarily cause a problem. In many cases it doesn't as
> >> > > >> >> >> function pointer equality is not an invariant a program relies upon
> >> > > >> >> >> (at least, for many functions, the property is not used). My previous
> >> > > >> >> >> comment has mentioned two cases.
> >> > > >> >> >>
> >> > > >> >> >> 1 likely causes a problem, but technically the shared object can define
> >> > > >> >> >> a protected data symbol without accessing it..
> >> > > >> >> >
> >> > > >> >> >These are unknown consequences.   We don't know what the worst
> >> > > >> >> >cases are.
> >> > > >> >>
> >> > > >> >> They are, just like when a shared object is linked with -Bsymbolic.
> >> > > >> >
> >> > > >> >They have to deal with it since it is done on purpose.
> >> > > >> >
> >> > > >> >> This patch focuses on changing the x86 default to a sane value (matching
> >> > > >> >> aarch64/arm/powerpc64/riscv/etc) and enabling future removal of
> >> > > >> >> `extern_protected_data`.  If you want to switch to
> >> > > >> >> indirect-extern-access default for x86, while I think unnecessary, I will not object.
> >> > > >> >
> >> > > >> >extern_protected_data can be safely removed only when
> >> > > >> >direct access to external symbols are disallowed.   We can't
> >> > > >> >have both ways.
> >> > > >>
> >> > > >> Just define has_no_copy_on_protected to 1 to catch the usage at link
> >> > > >
> >> > > >This is the same as using -z indirect-extern-access on executable.
> >> > > >
> >> > > >> time.  ld's aarch64 port has such an error by default.  gold and ld.lld
> >> > > >> has such an error for a long time now.
> >> > > >>
> >> > > >> We don't need to worry about whether this stricter behavior breaks user
> >> > > >> programs.  As is, protected symbol using GCC+binutils provides no
> >> > > >> benefit.  Programs just avoid protected data symbols.
> >> > > >
> >> > > >Then there should be no problems with
> >> > > >GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
> >> > > >I'd like to disallow copy relocation on protected symbols at run-time
> >> > > >when there are unknown consequences.
> >> > >
> >> > > Enabling GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS for x86 by default
> >> > > has these effects:
> >> > >
> >> > > * 280+ check-ld tests will fail
> >> >
> >> > They should be updated.
> >>
> >> That will be a huge effort and may not be so necessary. See below.
> >>
> >> > > * The GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note appears
> >> >
> >> > It will disallow copy relocation on protected symbols at run-time.
> >> >
> >> > >    redundant. It encodes an intention explicit but the intention is
> >> > >    in ld aarch64, gold (all ports), and lld (all ports) with no extra option.
> >> > >
> >> > > IMO, we should do these:
> >> > >
> >> > > * push this commit
> >> > > * treat elf_has_no_copy_on_protected as always true and remove all GNU_PROPERTY_NO_COPY_ON_PROTECTED
> >> > >
> >> > > Again, I understand that there is concern about protected data symbols
> >> > > in shared object.  But as is, nobody uses protected symbols in shared objects.
> >> > > My
> >> > >
> >> > >    // gcc -fpic -shared -fuse-ld=bfd
> >> > >    __attribute__((visibility("protected"))) void *foo() {
> >> > >      return (void *)foo;
> >> > >    }
> >> > >
> >> > > example indicates that protected future symbol is also broken.
> >> >
> >> > To get protected symbol to work properly on x86-64, copy relocation on protected
> >> > symbols should be disallowed at run-time.
> >>
> >> Yes that GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will change the
> >> glibc warning to an error, but we don't need to hurry making the cases
> >> an error.  Since protected symbols do not have performance benefits (in
> >> gcc's many ports and GNU ld's x86 port), people avoid using it.  My
> >> advise is to just let ld stop producing executables which will trigger
> >> glibc warning/error (this has precedent in gold and ld.lld and FreeBSD's
> >> adoption of ld.lld means that this goes actually very well).  Projects
> >> will gradually fix their builds to enable indirect external access in
> >> the rare case they encounter protected symbols in shared objects.  Then
> >> in a few years, the glibc warning can naturally upgrade to an error,
> >> with possibly a method (e.g. similar to LD_DYNAMIC_WEAK) to downgrade to
> >> a warning.  Finally, remove the opt-out method.
> >>
> >> With this scheme no GNU property is needed.
> >
> >Then, linker should disallow copy relocation against protected symbols
> >and non-canonical reference to canonical protected functions.
> >
> >Something like this.
> >
> >
> >H.J.
> >----
> >x86: Disallow invalid relocations against protected symbols
> >
> >Since glibc 2.36 will issue warnings for copy relocation against
> >protected symbols and non-canonical reference to canonical protected
> >functions, change the linker to always disallow such relocations.
>
> Thanks.  When reporting relocation diagnostics, making the condition
> stricter by removing elf_has_indirect_extern_access is the right
> direction.
>
>
> Your patch alone isn't sufficient to make -fpic -shared below work:

My patch is on top of yours.

> __attribute__((visibility("protected"))) void *foo() {
>    return (void *)foo;
> }
>
>
> >bfd/
> >
> >       * elf32-i386.c (elf_i386_scan_relocs): Remove check for
> >       elf_has_indirect_extern_access.
> >       * elf64-x86-64.c (elf_x86_64_scan_relocs): Likewise.
> >       (elf_x86_64_relocate_section): Remove check for
> >       elf_has_no_copy_on_protected.
> >       * elfxx-x86.c (elf_x86_allocate_dynrelocs): Check for building
> >       executable instead of elf_has_no_copy_on_protected.
> >       (_bfd_x86_elf_adjust_dynamic_symbol): Disallow copy relocation
> >       against non-copyable protected symbol.
> >       * elfxx-x86.h (SYMBOL_NO_COPYRELOC): Remove check for
> >       elf_has_no_copy_on_protected.
> >
> >ld/
> >
> >       * testsuite/ld-i386/i386.exp: Expect linker error for PR ld/17709
> >       test.
> >       * testsuite/ld-i386/pr17709.rd: Removed.
> >       * testsuite/ld-i386/pr17709.err: New file.
> >       * testsuite/ld-x86-64/pr17709.rd: Removed.
> >       * testsuite/ld-x86-64/pr17709.err: New file.
> >       * testsuite/ld-x86-64/pr28875-func.err: Updated.
> >       * testsuite/ld-x86-64/x86-64.exp: Expect linker error for PR
> >       ld/17709 test.  Add tests for function pointer against protected
> >       function.
> >---
> > bfd/elf32-i386.c                        |  3 +--
> > bfd/elf64-x86-64.c                      | 10 +++-------
> > bfd/elfxx-x86.c                         | 21 +++++++++++++++++++--
> > bfd/elfxx-x86.h                         |  3 +--
> > ld/testsuite/ld-i386/i386.exp           |  2 +-
> > ld/testsuite/ld-i386/pr17709.err        |  2 ++
> > ld/testsuite/ld-i386/pr17709.rd         |  4 ----
> > ld/testsuite/ld-x86-64/pr17709.err      |  2 ++
> > ld/testsuite/ld-x86-64/pr17709.rd       |  4 ----
> > ld/testsuite/ld-x86-64/pr28875-func.err |  2 +-
> > ld/testsuite/ld-x86-64/x86-64.exp       | 18 +++++++++++++++++-
> > 11 files changed, 47 insertions(+), 24 deletions(-)
> > create mode 100644 ld/testsuite/ld-i386/pr17709.err
> > delete mode 100644 ld/testsuite/ld-i386/pr17709.rd
> > create mode 100644 ld/testsuite/ld-x86-64/pr17709.err
> > delete mode 100644 ld/testsuite/ld-x86-64/pr17709.rd
> >
> >diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> >index 04a972e646d..cfb0085b245 100644
> >--- a/bfd/elf32-i386.c
> >+++ b/bfd/elf32-i386.c
> >@@ -1812,8 +1812,7 @@ elf_i386_scan_relocs (bfd *abfd,
> >                     && h->type == STT_FUNC
> >                     && eh->def_protected
> >                     && !SYMBOL_DEFINED_NON_SHARED_P (h)
> >-                    && h->def_dynamic
> >-                    && elf_has_indirect_extern_access (h->root.u.def.section->owner))
> >+                    && h->def_dynamic)
> >                   {
> >                     /* Disallow non-canonical reference to canonical
> >                        protected function.  */
> >diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> >index 3abc68a4127..62a9a22317a 100644
> >--- a/bfd/elf64-x86-64.c
> >+++ b/bfd/elf64-x86-64.c
> >@@ -2255,8 +2255,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
> >                     && h->type == STT_FUNC
> >                     && eh->def_protected
> >                     && !SYMBOL_DEFINED_NON_SHARED_P (h)
> >-                    && h->def_dynamic
> >-                    && elf_has_indirect_extern_access (h->root.u.def.section->owner))
> >+                    && h->def_dynamic)
> >                   {
> >                     /* Disallow non-canonical reference to canonical
> >                        protected function.  */
> >@@ -3156,8 +3155,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> >              || (h != NULL
> >                  && !h->root.linker_def
> >                  && !h->root.ldscript_def
> >-                 && eh->def_protected
> >-                 && elf_has_no_copy_on_protected (h->root.u.def.section->owner)));
> >+                 && eh->def_protected));
> >
> >         if ((input_section->flags & SEC_ALLOC) != 0
> >             && (input_section->flags & SEC_READONLY) != 0
> >@@ -4097,9 +4095,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> >           {
> >           case R_X86_64_32S:
> >             sec = h->root.u.def.section;
> >-            if ((info->nocopyreloc
> >-                 || (eh->def_protected
> >-                     && elf_has_no_copy_on_protected (h->root.u.def.section->owner)))
> >+            if ((info->nocopyreloc || eh->def_protected)
> >                 && !(h->root.u.def.section->flags & SEC_CODE))
> >               return elf_x86_64_need_pic (info, input_bfd, input_section,
> >                                           h, NULL, NULL, howto);
> >diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
> >index 18f3d335458..7fb972752b3 100644
> >--- a/bfd/elfxx-x86.c
> >+++ b/bfd/elfxx-x86.c
> >@@ -524,8 +524,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
> >     {
> >       asection *sreloc;
> >
> >-      if (eh->def_protected
> >-        && elf_has_no_copy_on_protected (h->root.u.def.section->owner))
> >+      if (eh->def_protected && bfd_link_executable (info))
> >       {
> >         /* Disallow copy relocation against non-copyable protected
> >            symbol.  */
> >@@ -3041,6 +3040,24 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
> >     }
> >   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
> >     {
> >+      if (eh->def_protected && bfd_link_executable (info))
> >+      for (p = h->dyn_relocs; p != NULL; p = p->next)
> >+        {
> >+          /* Disallow copy relocation against non-copyable protected
> >+             symbol.  */
> >+          s = p->sec->output_section;
> >+          if (s != NULL && (s->flags & SEC_READONLY) != 0)
> >+            {
> >+              info->callbacks->einfo
> >+                /* xgettext:c-format */
> >+                (_("%F%P: %pB: copy relocation against non-copyable "
> >+                   "protected symbol `%s' in %pB\n"),
> >+                 p->sec->owner, h->root.root.string,
> >+                 h->root.u.def.section->owner);
> >+              return false;
> >+            }
> >+        }
> >+
> >       srel->size += htab->sizeof_reloc;
> >       h->needs_copy = 1;
> >     }
> >diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
> >index 77fb1ad72bc..7d23893938c 100644
> >--- a/bfd/elfxx-x86.h
> >+++ b/bfd/elfxx-x86.h
> >@@ -135,12 +135,11 @@
> >
> > /* Should copy relocation be generated for a symbol.  Don't generate
> >    copy relocation against a protected symbol defined in a shared
> >-   object with GNU_PROPERTY_NO_COPY_ON_PROTECTED.  */
> >+   object.  */
> > #define SYMBOL_NO_COPYRELOC(INFO, EH) \
> >   ((EH)->def_protected \
> >    && ((EH)->elf.root.type == bfd_link_hash_defined \
> >        || (EH)->elf.root.type == bfd_link_hash_defweak) \
> >-   && elf_has_no_copy_on_protected ((EH)->elf.root.u.def.section->owner) \
> >    && ((EH)->elf.root.u.def.section->owner->flags & DYNAMIC) != 0 \
> >    && ((EH)->elf.root.u.def.section->flags & SEC_CODE) == 0)
> >
> >diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
> >index b4f7de49fd5..0ab9c001336 100644
> >--- a/ld/testsuite/ld-i386/i386.exp
> >+++ b/ld/testsuite/ld-i386/i386.exp
> >@@ -224,7 +224,7 @@ set i386tests {
> >      "--32 -mx86-used-note=yes" {pr17709a.s} {} "libpr17709.so"}
> >     {"PR ld/17709 (2)" "-melf_i386 tmpdir/libpr17709.so" ""
> >      "--32 -mx86-used-note=yes"
> >-     {pr17709b.s} {{readelf -r pr17709.rd}} "pr17709"}
> >+     {pr17709b.s} {{ld "pr17709.err"}} "pr17709"}
> >     {"Build pr19827a.o" "" ""
> >      "--32 -mx86-used-note=yes" { pr19827a.S }}
> >     {"Build pr19827b.so" "-melf_i386 -shared" ""
> >diff --git a/ld/testsuite/ld-i386/pr17709.err b/ld/testsuite/ld-i386/pr17709.err
> >new file mode 100644
> >index 00000000000..fa6a4bacce3
> >--- /dev/null
> >+++ b/ld/testsuite/ld-i386/pr17709.err
> >@@ -0,0 +1,2 @@
> >+.*: tmpdir/pr17709b.o: copy relocation against non-copyable protected symbol `foo' in tmpdir/libpr17709.so
> >+#...
> >diff --git a/ld/testsuite/ld-i386/pr17709.rd b/ld/testsuite/ld-i386/pr17709.rd
> >deleted file mode 100644
> >index 8414784b736..00000000000
> >--- a/ld/testsuite/ld-i386/pr17709.rd
> >+++ /dev/null
> >@@ -1,4 +0,0 @@
> >-
> >-Relocation section '.rel\..*' at offset .* contains 1 entry:
> >- Offset     Info    Type            Sym\.Value  Sym\. Name
> >-[0-9a-f ]+R_386_COPY +[0-9a-f]+ +foo
> >diff --git a/ld/testsuite/ld-x86-64/pr17709.err b/ld/testsuite/ld-x86-64/pr17709.err
> >new file mode 100644
> >index 00000000000..fa6a4bacce3
> >--- /dev/null
> >+++ b/ld/testsuite/ld-x86-64/pr17709.err
> >@@ -0,0 +1,2 @@
> >+.*: tmpdir/pr17709b.o: copy relocation against non-copyable protected symbol `foo' in tmpdir/libpr17709.so
> >+#...
> >diff --git a/ld/testsuite/ld-x86-64/pr17709.rd b/ld/testsuite/ld-x86-64/pr17709.rd
> >deleted file mode 100644
> >index beffd3cb34c..00000000000
> >--- a/ld/testsuite/ld-x86-64/pr17709.rd
> >+++ /dev/null
> >@@ -1,4 +0,0 @@
> >-
> >-Relocation section '.rela\..*' at offset .* contains 1 entry:
> >- +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
> >-[0-9a-f ]+R_X86_64_COPY+[0-9a-f ]+ +foo \+ 0
> >diff --git a/ld/testsuite/ld-x86-64/pr28875-func.err b/ld/testsuite/ld-x86-64/pr28875-func.err
> >index 64e961cb3d4..f6f4658deaf 100644
> >--- a/ld/testsuite/ld-x86-64/pr28875-func.err
> >+++ b/ld/testsuite/ld-x86-64/pr28875-func.err
> >@@ -1,2 +1,2 @@
> >-.*: tmpdir/protected-func-1b.o: non-canonical reference to canonical protected function `protected_func_1a' in tmpdir/libprotected-func-2b.so
> >+.*: tmpdir/protected-func-1b.o: non-canonical reference to canonical protected function `protected_func_1a' in tmpdir/libprotected-func-2..so
> > #...
> >diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
> >index a096c0b9d0f..e6a834a2a61 100644
> >--- a/ld/testsuite/ld-x86-64/x86-64.exp
> >+++ b/ld/testsuite/ld-x86-64/x86-64.exp
> >@@ -177,7 +177,7 @@ set x86_64tests {
> >     {"PR ld/17709 (1)" "-melf_x86_64 -shared" ""
> >      "--64" {pr17709a.s} {} "libpr17709.so"}
> >     {"PR ld/17709 (2)" "-melf_x86_64 tmpdir/libpr17709.so" ""
> >-     "--64" {pr17709b.s} {{readelf -rW pr17709.rd}} "pr17709"}
> >+     "--64" {pr17709b.s} {{ld "pr17709.err"}} "pr17709"}
> >     {"Build pr19827a.o" "" ""
> >      "--64" { pr19827a.S }}
> >     {"Build pr19827b.so" "-melf_x86_64 -shared" ""
> >@@ -1383,6 +1383,22 @@ if { [isnative] && [check_compiler_available] } {
> >           {{error_output "pr28875-func.err"}} \
> >           "protected-func-2" \
> >       ] \
> >+      [list \
> >+          "Build libprotected-func-2c.so" \
> >+          "-shared" \
> >+          "-fPIC -Wa,-mx86-used-note=yes" \
> >+          { protected-func-2c.c } \
> >+          {}  \
> >+          "libprotected-func-2c.so" \
> >+      ] \
> >+      [list \
> >+          "Build protected-func-2a without PIE" \
> >+          "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-2c.so" \
> >+          "$NOPIE_CFLAGS -Wa,-mx86-used-note=yes" \
> >+          { protected-func-1b.c } \
> >+          {{error_output "pr28875-func.err"}} \
> >+          "protected-func-2a" \
> >+      ] \
> >       [list \
> >           "Build libprotected-data-1a.so" \
> >           "-shared -z noindirect-extern-access" \
> >--
> >2.36.1
> >



-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-07-19  3:38                                 ` H.J. Lu
@ 2022-07-19  4:02                                   ` Fangrui Song
  2022-07-19 15:40                                     ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Fangrui Song @ 2022-07-19  4:02 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On 2022-07-18, H.J. Lu wrote:
>On Mon, Jul 18, 2022 at 8:13 PM Fangrui Song <i@maskray.me> wrote:
>>
>> On 2022-07-18, H.J. Lu wrote:
>> >On Mon, Jun 27, 2022 at 09:18:27PM -0700, Fangrui Song wrote:
>> >> On 2022-06-27, H.J. Lu wrote:
>> >> > On Mon, Jun 27, 2022 at 8:44 PM Fangrui Song <i@maskray.me> wrote:
>> >> > >
>> >> > > On 2022-06-27, H.J. Lu wrote:
>> >> > > >On Mon, Jun 27, 2022 at 8:07 PM Fangrui Song <i@maskray.me> wrote:
>> >> > > >>
>> >> > > >> On 2022-06-27, H.J. Lu wrote:
>> >> > > >> >On Mon, Jun 27, 2022 at 11:46 AM Fangrui Song <i@maskray.me> wrote:
>> >> > > >> >>
>> >> > > >> >> On 2022-06-27, H.J. Lu wrote:
>> >> > > >> >> >On Mon, Jun 27, 2022 at 10:53 AM Fangrui Song <i@maskray.me> wrote:
>> >> > > >> >> >>
>> >> > > >> >> >> On 2022-06-27, H.J. Lu wrote:
>> >> > > >> >> >> >On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
>> >> > > >> >> >> >>
>> >> > > >> >> >> >> On 2022-06-27, H.J. Lu wrote:
>> >> > > >> >> >> >> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
>> >> > > >> >> >> >> >>
>> >> > > >> >> >> >> >> On 2022-06-26, H.J. Lu wrote:
>> >> > > >> >> >> >> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
>> >> > > >> >> >> >> >> >>
>> >> > > >> >> >> >> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
>> >> > > >> >> >> >> >> >> 2 noticeable effects for -shared:
>> >> > > >> >> >> >> >> >>
>> >> > > >> >> >> >> >> >> * GOT-generating relocations referencing a protected data symbol no
>> >> > > >> >> >> >> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
>> >> > > >> >> >> >> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
>> >> > > >> >> >> >> >> >>   confusing diagnostic below.
>> >> > > >> >> >> >> >> >>
>> >> > > >> >> >> >> >> >>     __attribute__((visibility("protected"))) void *foo() {
>> >> > > >> >> >> >> >> >>       return (void *)foo;
>> >> > > >> >> >> >> >> >>     }
>> >> > > >> >> >> >> >> >>
>> >> > > >> >> >> >> >> >>     // gcc -fpic -shared -fuse-ld=bfd
>> >> > > >> >> >> >> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
>> >> > > >> >> >> >> >> >>
>> >> > > >> >> >> >> >> >> The new behavior matches arm, aarch64 (commit
>> >> > > >> >> >> >> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
>> >> > > >> >> >> >> >> >> linkers: gold and ld.lld.
>> >> > > >> >> >> >> >> >>
>> >> > > >> >> >> >> >> >> Note: if some code tries to use direct access relocations to take the
>> >> > > >> >> >> >> >> >> address of foo, the pointer equality will break, but the error should be
>> >> > > >> >> >> >> >> >> reported on the executable link, not on the innocent shared object link.
>> >> > > >> >> >> >> >> >> glibc 2.36 will give a warning at relocation resolving time.
>> >> > > >> >> >> >> >> >
>> >> > > >> >> >> >> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
>> >> > > >> >> >> >> >> >-z  indirect-extern-access with -shared by default instead?
>> >> > > >> >> >> >> >>
>> >> > > >> >> >> >> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
>> >> > > >> >> >> >> >> bfd/elf-properties.c:654 will create a
>> >> > > >> >> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
>> >> > > >> >> >> >> >> This will probably be unexpected (and check-ld will have 280+ failures).
>> >> > > >> >> >> >> >
>> >> > > >> >> >> >> >This is normal when the default behavior is changed.  You can pass
>> >> > > >> >> >> >> >-z noindirect-extern-access to these testcases.
>> >> > > >> >> >> >>
>> >> > > >> >> >> >> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
>> >> > > >> >> >> >> significant behavior change and may unnecessarily break user programs
>> >> > > >> >> >> >> (glibc will report an error instead of a warning).
>> >> > > >> >> >> >
>> >> > > >> >> >> >If glibc reports an error, it is a real bug with unknown consequences
>> >> > > >> >> >> >when the copy in the executable is out of sync with the protected
>> >> > > >> >> >> >symbol in the shared library,
>> >> > > >> >> >>
>> >> > > >> >> >> Not necessary.
>> >> > > >> >> >>
>> >> > > >> >> >> In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
>> >> > > >> >> >> 1 (copy relocations) and 2 (non-zero value of an undefined function
>> >> > > >> >> >> symbol) on
>> >> > > >> >> >> https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html
>> >> > > >> >> >>
>> >> > > >> >> >> 2 does not necessarily cause a problem. In many cases it doesn't as
>> >> > > >> >> >> function pointer equality is not an invariant a program relies upon
>> >> > > >> >> >> (at least, for many functions, the property is not used). My previous
>> >> > > >> >> >> comment has mentioned two cases.
>> >> > > >> >> >>
>> >> > > >> >> >> 1 likely causes a problem, but technically the shared object can define
>> >> > > >> >> >> a protected data symbol without accessing it..
>> >> > > >> >> >
>> >> > > >> >> >These are unknown consequences.   We don't know what the worst
>> >> > > >> >> >cases are.
>> >> > > >> >>
>> >> > > >> >> They are, just like when a shared object is linked with -Bsymbolic.
>> >> > > >> >
>> >> > > >> >They have to deal with it since it is done on purpose.
>> >> > > >> >
>> >> > > >> >> This patch focuses on changing the x86 default to a sane value (matching
>> >> > > >> >> aarch64/arm/powerpc64/riscv/etc) and enabling future removal of
>> >> > > >> >> `extern_protected_data`.  If you want to switch to
>> >> > > >> >> indirect-extern-access default for x86, while I think unnecessary, I will not object.
>> >> > > >> >
>> >> > > >> >extern_protected_data can be safely removed only when
>> >> > > >> >direct access to external symbols are disallowed.   We can't
>> >> > > >> >have both ways.
>> >> > > >>
>> >> > > >> Just define has_no_copy_on_protected to 1 to catch the usage at link
>> >> > > >
>> >> > > >This is the same as using -z indirect-extern-access on executable.
>> >> > > >
>> >> > > >> time.  ld's aarch64 port has such an error by default.  gold and ld.lld
>> >> > > >> has such an error for a long time now.
>> >> > > >>
>> >> > > >> We don't need to worry about whether this stricter behavior breaks user
>> >> > > >> programs.  As is, protected symbol using GCC+binutils provides no
>> >> > > >> benefit.  Programs just avoid protected data symbols.
>> >> > > >
>> >> > > >Then there should be no problems with
>> >> > > >GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
>> >> > > >I'd like to disallow copy relocation on protected symbols at run-time
>> >> > > >when there are unknown consequences.
>> >> > >
>> >> > > Enabling GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS for x86 by default
>> >> > > has these effects:
>> >> > >
>> >> > > * 280+ check-ld tests will fail
>> >> >
>> >> > They should be updated.
>> >>
>> >> That will be a huge effort and may not be so necessary. See below.
>> >>
>> >> > > * The GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note appears
>> >> >
>> >> > It will disallow copy relocation on protected symbols at run-time.
>> >> >
>> >> > >    redundant. It encodes an intention explicit but the intention is
>> >> > >    in ld aarch64, gold (all ports), and lld (all ports) with no extra option.
>> >> > >
>> >> > > IMO, we should do these:
>> >> > >
>> >> > > * push this commit
>> >> > > * treat elf_has_no_copy_on_protected as always true and remove all GNU_PROPERTY_NO_COPY_ON_PROTECTED
>> >> > >
>> >> > > Again, I understand that there is concern about protected data symbols
>> >> > > in shared object.  But as is, nobody uses protected symbols in shared objects.
>> >> > > My
>> >> > >
>> >> > >    // gcc -fpic -shared -fuse-ld=bfd
>> >> > >    __attribute__((visibility("protected"))) void *foo() {
>> >> > >      return (void *)foo;
>> >> > >    }
>> >> > >
>> >> > > example indicates that protected future symbol is also broken.
>> >> >
>> >> > To get protected symbol to work properly on x86-64, copy relocation on protected
>> >> > symbols should be disallowed at run-time.
>> >>
>> >> Yes that GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will change the
>> >> glibc warning to an error, but we don't need to hurry making the cases
>> >> an error.  Since protected symbols do not have performance benefits (in
>> >> gcc's many ports and GNU ld's x86 port), people avoid using it.  My
>> >> advise is to just let ld stop producing executables which will trigger
>> >> glibc warning/error (this has precedent in gold and ld.lld and FreeBSD's
>> >> adoption of ld.lld means that this goes actually very well).  Projects
>> >> will gradually fix their builds to enable indirect external access in
>> >> the rare case they encounter protected symbols in shared objects.  Then
>> >> in a few years, the glibc warning can naturally upgrade to an error,
>> >> with possibly a method (e.g. similar to LD_DYNAMIC_WEAK) to downgrade to
>> >> a warning.  Finally, remove the opt-out method.
>> >>
>> >> With this scheme no GNU property is needed.
>> >
>> >Then, linker should disallow copy relocation against protected symbols
>> >and non-canonical reference to canonical protected functions.
>> >
>> >Something like this.
>> >
>> >
>> >H.J.
>> >----
>> >x86: Disallow invalid relocations against protected symbols
>> >
>> >Since glibc 2.36 will issue warnings for copy relocation against
>> >protected symbols and non-canonical reference to canonical protected
>> >functions, change the linker to always disallow such relocations.
>>
>> Thanks.  When reporting relocation diagnostics, making the condition
>> stricter by removing elf_has_indirect_extern_access is the right
>> direction.
>>
>>
>> Your patch alone isn't sufficient to make -fpic -shared below work:
>
>My patch is on top of yours.

Thanks.  If you are happy with either, feel free to push them.

>> __attribute__((visibility("protected"))) void *foo() {
>>    return (void *)foo;
>> }
>>
>>
>> >bfd/
>> >
>> >       * elf32-i386.c (elf_i386_scan_relocs): Remove check for
>> >       elf_has_indirect_extern_access.
>> >       * elf64-x86-64.c (elf_x86_64_scan_relocs): Likewise.
>> >       (elf_x86_64_relocate_section): Remove check for
>> >       elf_has_no_copy_on_protected.
>> >       * elfxx-x86.c (elf_x86_allocate_dynrelocs): Check for building
>> >       executable instead of elf_has_no_copy_on_protected.
>> >       (_bfd_x86_elf_adjust_dynamic_symbol): Disallow copy relocation
>> >       against non-copyable protected symbol.
>> >       * elfxx-x86.h (SYMBOL_NO_COPYRELOC): Remove check for
>> >       elf_has_no_copy_on_protected.
>> >
>> >ld/
>> >
>> >       * testsuite/ld-i386/i386.exp: Expect linker error for PR ld/17709
>> >       test.
>> >       * testsuite/ld-i386/pr17709.rd: Removed.
>> >       * testsuite/ld-i386/pr17709.err: New file.
>> >       * testsuite/ld-x86-64/pr17709.rd: Removed.
>> >       * testsuite/ld-x86-64/pr17709.err: New file.
>> >       * testsuite/ld-x86-64/pr28875-func.err: Updated.
>> >       * testsuite/ld-x86-64/x86-64.exp: Expect linker error for PR
>> >       ld/17709 test.  Add tests for function pointer against protected
>> >       function.
>> >---
>> > bfd/elf32-i386.c                        |  3 +--
>> > bfd/elf64-x86-64.c                      | 10 +++-------
>> > bfd/elfxx-x86.c                         | 21 +++++++++++++++++++--
>> > bfd/elfxx-x86.h                         |  3 +--
>> > ld/testsuite/ld-i386/i386.exp           |  2 +-
>> > ld/testsuite/ld-i386/pr17709.err        |  2 ++
>> > ld/testsuite/ld-i386/pr17709.rd         |  4 ----
>> > ld/testsuite/ld-x86-64/pr17709.err      |  2 ++
>> > ld/testsuite/ld-x86-64/pr17709.rd       |  4 ----
>> > ld/testsuite/ld-x86-64/pr28875-func.err |  2 +-
>> > ld/testsuite/ld-x86-64/x86-64.exp       | 18 +++++++++++++++++-
>> > 11 files changed, 47 insertions(+), 24 deletions(-)
>> > create mode 100644 ld/testsuite/ld-i386/pr17709.err
>> > delete mode 100644 ld/testsuite/ld-i386/pr17709.rd
>> > create mode 100644 ld/testsuite/ld-x86-64/pr17709.err
>> > delete mode 100644 ld/testsuite/ld-x86-64/pr17709.rd
>> >
>> >diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
>> >index 04a972e646d..cfb0085b245 100644
>> >--- a/bfd/elf32-i386.c
>> >+++ b/bfd/elf32-i386.c
>> >@@ -1812,8 +1812,7 @@ elf_i386_scan_relocs (bfd *abfd,
>> >                     && h->type == STT_FUNC
>> >                     && eh->def_protected
>> >                     && !SYMBOL_DEFINED_NON_SHARED_P (h)
>> >-                    && h->def_dynamic
>> >-                    && elf_has_indirect_extern_access (h->root.u.def.section->owner))
>> >+                    && h->def_dynamic)
>> >                   {
>> >                     /* Disallow non-canonical reference to canonical
>> >                        protected function.  */
>> >diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
>> >index 3abc68a4127..62a9a22317a 100644
>> >--- a/bfd/elf64-x86-64.c
>> >+++ b/bfd/elf64-x86-64.c
>> >@@ -2255,8 +2255,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
>> >                     && h->type == STT_FUNC
>> >                     && eh->def_protected
>> >                     && !SYMBOL_DEFINED_NON_SHARED_P (h)
>> >-                    && h->def_dynamic
>> >-                    && elf_has_indirect_extern_access (h->root.u.def.section->owner))
>> >+                    && h->def_dynamic)
>> >                   {
>> >                     /* Disallow non-canonical reference to canonical
>> >                        protected function.  */
>> >@@ -3156,8 +3155,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
>> >              || (h != NULL
>> >                  && !h->root.linker_def
>> >                  && !h->root.ldscript_def
>> >-                 && eh->def_protected
>> >-                 && elf_has_no_copy_on_protected (h->root.u.def.section->owner)));
>> >+                 && eh->def_protected));
>> >
>> >         if ((input_section->flags & SEC_ALLOC) != 0
>> >             && (input_section->flags & SEC_READONLY) != 0
>> >@@ -4097,9 +4095,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
>> >           {
>> >           case R_X86_64_32S:
>> >             sec = h->root.u.def.section;
>> >-            if ((info->nocopyreloc
>> >-                 || (eh->def_protected
>> >-                     && elf_has_no_copy_on_protected (h->root.u.def.section->owner)))
>> >+            if ((info->nocopyreloc || eh->def_protected)
>> >                 && !(h->root.u.def.section->flags & SEC_CODE))
>> >               return elf_x86_64_need_pic (info, input_bfd, input_section,
>> >                                           h, NULL, NULL, howto);
>> >diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
>> >index 18f3d335458..7fb972752b3 100644
>> >--- a/bfd/elfxx-x86.c
>> >+++ b/bfd/elfxx-x86.c
>> >@@ -524,8 +524,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
>> >     {
>> >       asection *sreloc;
>> >
>> >-      if (eh->def_protected
>> >-        && elf_has_no_copy_on_protected (h->root.u.def.section->owner))
>> >+      if (eh->def_protected && bfd_link_executable (info))
>> >       {
>> >         /* Disallow copy relocation against non-copyable protected
>> >            symbol.  */
>> >@@ -3041,6 +3040,24 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
>> >     }
>> >   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
>> >     {
>> >+      if (eh->def_protected && bfd_link_executable (info))
>> >+      for (p = h->dyn_relocs; p != NULL; p = p->next)
>> >+        {
>> >+          /* Disallow copy relocation against non-copyable protected
>> >+             symbol.  */
>> >+          s = p->sec->output_section;
>> >+          if (s != NULL && (s->flags & SEC_READONLY) != 0)
>> >+            {
>> >+              info->callbacks->einfo
>> >+                /* xgettext:c-format */
>> >+                (_("%F%P: %pB: copy relocation against non-copyable "
>> >+                   "protected symbol `%s' in %pB\n"),
>> >+                 p->sec->owner, h->root.root.string,
>> >+                 h->root.u.def.section->owner);
>> >+              return false;
>> >+            }
>> >+        }
>> >+
>> >       srel->size += htab->sizeof_reloc;
>> >       h->needs_copy = 1;
>> >     }
>> >diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
>> >index 77fb1ad72bc..7d23893938c 100644
>> >--- a/bfd/elfxx-x86.h
>> >+++ b/bfd/elfxx-x86.h
>> >@@ -135,12 +135,11 @@
>> >
>> > /* Should copy relocation be generated for a symbol.  Don't generate
>> >    copy relocation against a protected symbol defined in a shared
>> >-   object with GNU_PROPERTY_NO_COPY_ON_PROTECTED.  */
>> >+   object.  */
>> > #define SYMBOL_NO_COPYRELOC(INFO, EH) \
>> >   ((EH)->def_protected \
>> >    && ((EH)->elf.root.type == bfd_link_hash_defined \
>> >        || (EH)->elf.root.type == bfd_link_hash_defweak) \
>> >-   && elf_has_no_copy_on_protected ((EH)->elf.root.u.def.section->owner) \
>> >    && ((EH)->elf.root.u.def.section->owner->flags & DYNAMIC) != 0 \
>> >    && ((EH)->elf.root.u.def.section->flags & SEC_CODE) == 0)
>> >
>> >diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
>> >index b4f7de49fd5..0ab9c001336 100644
>> >--- a/ld/testsuite/ld-i386/i386.exp
>> >+++ b/ld/testsuite/ld-i386/i386.exp
>> >@@ -224,7 +224,7 @@ set i386tests {
>> >      "--32 -mx86-used-note=yes" {pr17709a.s} {} "libpr17709.so"}
>> >     {"PR ld/17709 (2)" "-melf_i386 tmpdir/libpr17709.so" ""
>> >      "--32 -mx86-used-note=yes"
>> >-     {pr17709b.s} {{readelf -r pr17709.rd}} "pr17709"}
>> >+     {pr17709b.s} {{ld "pr17709.err"}} "pr17709"}
>> >     {"Build pr19827a.o" "" ""
>> >      "--32 -mx86-used-note=yes" { pr19827a.S }}
>> >     {"Build pr19827b.so" "-melf_i386 -shared" ""
>> >diff --git a/ld/testsuite/ld-i386/pr17709.err b/ld/testsuite/ld-i386/pr17709.err
>> >new file mode 100644
>> >index 00000000000..fa6a4bacce3
>> >--- /dev/null
>> >+++ b/ld/testsuite/ld-i386/pr17709.err
>> >@@ -0,0 +1,2 @@
>> >+.*: tmpdir/pr17709b.o: copy relocation against non-copyable protected symbol `foo' in tmpdir/libpr17709.so
>> >+#...
>> >diff --git a/ld/testsuite/ld-i386/pr17709.rd b/ld/testsuite/ld-i386/pr17709.rd
>> >deleted file mode 100644
>> >index 8414784b736..00000000000
>> >--- a/ld/testsuite/ld-i386/pr17709.rd
>> >+++ /dev/null
>> >@@ -1,4 +0,0 @@
>> >-
>> >-Relocation section '.rel\..*' at offset .* contains 1 entry:
>> >- Offset     Info    Type            Sym\.Value  Sym\. Name
>> >-[0-9a-f ]+R_386_COPY +[0-9a-f]+ +foo
>> >diff --git a/ld/testsuite/ld-x86-64/pr17709.err b/ld/testsuite/ld-x86-64/pr17709.err
>> >new file mode 100644
>> >index 00000000000..fa6a4bacce3
>> >--- /dev/null
>> >+++ b/ld/testsuite/ld-x86-64/pr17709.err
>> >@@ -0,0 +1,2 @@
>> >+.*: tmpdir/pr17709b.o: copy relocation against non-copyable protected symbol `foo' in tmpdir/libpr17709.so
>> >+#...
>> >diff --git a/ld/testsuite/ld-x86-64/pr17709.rd b/ld/testsuite/ld-x86-64/pr17709.rd
>> >deleted file mode 100644
>> >index beffd3cb34c..00000000000
>> >--- a/ld/testsuite/ld-x86-64/pr17709.rd
>> >+++ /dev/null
>> >@@ -1,4 +0,0 @@
>> >-
>> >-Relocation section '.rela\..*' at offset .* contains 1 entry:
>> >- +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
>> >-[0-9a-f ]+R_X86_64_COPY+[0-9a-f ]+ +foo \+ 0
>> >diff --git a/ld/testsuite/ld-x86-64/pr28875-func.err b/ld/testsuite/ld-x86-64/pr28875-func.err
>> >index 64e961cb3d4..f6f4658deaf 100644
>> >--- a/ld/testsuite/ld-x86-64/pr28875-func.err
>> >+++ b/ld/testsuite/ld-x86-64/pr28875-func.err
>> >@@ -1,2 +1,2 @@
>> >-.*: tmpdir/protected-func-1b.o: non-canonical reference to canonical protected function `protected_func_1a' in tmpdir/libprotected-func-2b.so
>> >+.*: tmpdir/protected-func-1b.o: non-canonical reference to canonical protected function `protected_func_1a' in tmpdir/libprotected-func-2..so
>> > #...
>> >diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
>> >index a096c0b9d0f..e6a834a2a61 100644
>> >--- a/ld/testsuite/ld-x86-64/x86-64.exp
>> >+++ b/ld/testsuite/ld-x86-64/x86-64.exp
>> >@@ -177,7 +177,7 @@ set x86_64tests {
>> >     {"PR ld/17709 (1)" "-melf_x86_64 -shared" ""
>> >      "--64" {pr17709a.s} {} "libpr17709.so"}
>> >     {"PR ld/17709 (2)" "-melf_x86_64 tmpdir/libpr17709.so" ""
>> >-     "--64" {pr17709b.s} {{readelf -rW pr17709.rd}} "pr17709"}
>> >+     "--64" {pr17709b.s} {{ld "pr17709.err"}} "pr17709"}
>> >     {"Build pr19827a.o" "" ""
>> >      "--64" { pr19827a.S }}
>> >     {"Build pr19827b.so" "-melf_x86_64 -shared" ""
>> >@@ -1383,6 +1383,22 @@ if { [isnative] && [check_compiler_available] } {
>> >           {{error_output "pr28875-func.err"}} \
>> >           "protected-func-2" \
>> >       ] \
>> >+      [list \
>> >+          "Build libprotected-func-2c.so" \
>> >+          "-shared" \
>> >+          "-fPIC -Wa,-mx86-used-note=yes" \
>> >+          { protected-func-2c.c } \
>> >+          {}  \
>> >+          "libprotected-func-2c.so" \
>> >+      ] \
>> >+      [list \
>> >+          "Build protected-func-2a without PIE" \
>> >+          "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-2c.so" \
>> >+          "$NOPIE_CFLAGS -Wa,-mx86-used-note=yes" \
>> >+          { protected-func-1b.c } \
>> >+          {{error_output "pr28875-func.err"}} \
>> >+          "protected-func-2a" \
>> >+      ] \
>> >       [list \
>> >           "Build libprotected-data-1a.so" \
>> >           "-shared -z noindirect-extern-access" \
>> >--
>> >2.36.1
>> >
>
>
>
>-- 
>H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-07-19  4:02                                   ` Fangrui Song
@ 2022-07-19 15:40                                     ` H.J. Lu
  2022-07-25 14:07                                       ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2022-07-19 15:40 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

On Mon, Jul 18, 2022 at 9:02 PM Fangrui Song <i@maskray.me> wrote:
>
> On 2022-07-18, H.J. Lu wrote:
> >On Mon, Jul 18, 2022 at 8:13 PM Fangrui Song <i@maskray.me> wrote:
> >>
> >> On 2022-07-18, H.J. Lu wrote:
> >> >On Mon, Jun 27, 2022 at 09:18:27PM -0700, Fangrui Song wrote:
> >> >> On 2022-06-27, H.J. Lu wrote:
> >> >> > On Mon, Jun 27, 2022 at 8:44 PM Fangrui Song <i@maskray.me> wrote:
> >> >> > >
> >> >> > > On 2022-06-27, H.J. Lu wrote:
> >> >> > > >On Mon, Jun 27, 2022 at 8:07 PM Fangrui Song <i@maskray.me> wrote:
> >> >> > > >>
> >> >> > > >> On 2022-06-27, H.J. Lu wrote:
> >> >> > > >> >On Mon, Jun 27, 2022 at 11:46 AM Fangrui Song <i@maskray.me> wrote:
> >> >> > > >> >>
> >> >> > > >> >> On 2022-06-27, H.J. Lu wrote:
> >> >> > > >> >> >On Mon, Jun 27, 2022 at 10:53 AM Fangrui Song <i@maskray.me> wrote:
> >> >> > > >> >> >>
> >> >> > > >> >> >> On 2022-06-27, H.J. Lu wrote:
> >> >> > > >> >> >> >On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
> >> >> > > >> >> >> >>
> >> >> > > >> >> >> >> On 2022-06-27, H.J. Lu wrote:
> >> >> > > >> >> >> >> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
> >> >> > > >> >> >> >> >>
> >> >> > > >> >> >> >> >> On 2022-06-26, H.J. Lu wrote:
> >> >> > > >> >> >> >> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
> >> >> > > >> >> >> >> >> >>
> >> >> > > >> >> >> >> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
> >> >> > > >> >> >> >> >> >> 2 noticeable effects for -shared:
> >> >> > > >> >> >> >> >> >>
> >> >> > > >> >> >> >> >> >> * GOT-generating relocations referencing a protected data symbol no
> >> >> > > >> >> >> >> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
> >> >> > > >> >> >> >> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
> >> >> > > >> >> >> >> >> >>   confusing diagnostic below.
> >> >> > > >> >> >> >> >> >>
> >> >> > > >> >> >> >> >> >>     __attribute__((visibility("protected"))) void *foo() {
> >> >> > > >> >> >> >> >> >>       return (void *)foo;
> >> >> > > >> >> >> >> >> >>     }
> >> >> > > >> >> >> >> >> >>
> >> >> > > >> >> >> >> >> >>     // gcc -fpic -shared -fuse-ld=bfd
> >> >> > > >> >> >> >> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> >> >> > > >> >> >> >> >> >>
> >> >> > > >> >> >> >> >> >> The new behavior matches arm, aarch64 (commit
> >> >> > > >> >> >> >> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
> >> >> > > >> >> >> >> >> >> linkers: gold and ld.lld.
> >> >> > > >> >> >> >> >> >>
> >> >> > > >> >> >> >> >> >> Note: if some code tries to use direct access relocations to take the
> >> >> > > >> >> >> >> >> >> address of foo, the pointer equality will break, but the error should be
> >> >> > > >> >> >> >> >> >> reported on the executable link, not on the innocent shared object link.
> >> >> > > >> >> >> >> >> >> glibc 2.36 will give a warning at relocation resolving time.
> >> >> > > >> >> >> >> >> >
> >> >> > > >> >> >> >> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
> >> >> > > >> >> >> >> >> >-z  indirect-extern-access with -shared by default instead?
> >> >> > > >> >> >> >> >>
> >> >> > > >> >> >> >> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
> >> >> > > >> >> >> >> >> bfd/elf-properties.c:654 will create a
> >> >> > > >> >> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
> >> >> > > >> >> >> >> >> This will probably be unexpected (and check-ld will have 280+ failures).
> >> >> > > >> >> >> >> >
> >> >> > > >> >> >> >> >This is normal when the default behavior is changed.  You can pass
> >> >> > > >> >> >> >> >-z noindirect-extern-access to these testcases.
> >> >> > > >> >> >> >>
> >> >> > > >> >> >> >> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
> >> >> > > >> >> >> >> significant behavior change and may unnecessarily break user programs
> >> >> > > >> >> >> >> (glibc will report an error instead of a warning).
> >> >> > > >> >> >> >
> >> >> > > >> >> >> >If glibc reports an error, it is a real bug with unknown consequences
> >> >> > > >> >> >> >when the copy in the executable is out of sync with the protected
> >> >> > > >> >> >> >symbol in the shared library,
> >> >> > > >> >> >>
> >> >> > > >> >> >> Not necessary.
> >> >> > > >> >> >>
> >> >> > > >> >> >> In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
> >> >> > > >> >> >> 1 (copy relocations) and 2 (non-zero value of an undefined function
> >> >> > > >> >> >> symbol) on
> >> >> > > >> >> >> https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html
> >> >> > > >> >> >>
> >> >> > > >> >> >> 2 does not necessarily cause a problem. In many cases it doesn't as
> >> >> > > >> >> >> function pointer equality is not an invariant a program relies upon
> >> >> > > >> >> >> (at least, for many functions, the property is not used). My previous
> >> >> > > >> >> >> comment has mentioned two cases.
> >> >> > > >> >> >>
> >> >> > > >> >> >> 1 likely causes a problem, but technically the shared object can define
> >> >> > > >> >> >> a protected data symbol without accessing it..
> >> >> > > >> >> >
> >> >> > > >> >> >These are unknown consequences.   We don't know what the worst
> >> >> > > >> >> >cases are.
> >> >> > > >> >>
> >> >> > > >> >> They are, just like when a shared object is linked with -Bsymbolic.
> >> >> > > >> >
> >> >> > > >> >They have to deal with it since it is done on purpose.
> >> >> > > >> >
> >> >> > > >> >> This patch focuses on changing the x86 default to a sane value (matching
> >> >> > > >> >> aarch64/arm/powerpc64/riscv/etc) and enabling future removal of
> >> >> > > >> >> `extern_protected_data`.  If you want to switch to
> >> >> > > >> >> indirect-extern-access default for x86, while I think unnecessary, I will not object.
> >> >> > > >> >
> >> >> > > >> >extern_protected_data can be safely removed only when
> >> >> > > >> >direct access to external symbols are disallowed.   We can't
> >> >> > > >> >have both ways.
> >> >> > > >>
> >> >> > > >> Just define has_no_copy_on_protected to 1 to catch the usage at link
> >> >> > > >
> >> >> > > >This is the same as using -z indirect-extern-access on executable.
> >> >> > > >
> >> >> > > >> time.  ld's aarch64 port has such an error by default.  gold and ld.lld
> >> >> > > >> has such an error for a long time now.
> >> >> > > >>
> >> >> > > >> We don't need to worry about whether this stricter behavior breaks user
> >> >> > > >> programs.  As is, protected symbol using GCC+binutils provides no
> >> >> > > >> benefit.  Programs just avoid protected data symbols.
> >> >> > > >
> >> >> > > >Then there should be no problems with
> >> >> > > >GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
> >> >> > > >I'd like to disallow copy relocation on protected symbols at run-time
> >> >> > > >when there are unknown consequences.
> >> >> > >
> >> >> > > Enabling GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS for x86 by default
> >> >> > > has these effects:
> >> >> > >
> >> >> > > * 280+ check-ld tests will fail
> >> >> >
> >> >> > They should be updated.
> >> >>
> >> >> That will be a huge effort and may not be so necessary. See below.
> >> >>
> >> >> > > * The GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note appears
> >> >> >
> >> >> > It will disallow copy relocation on protected symbols at run-time.
> >> >> >
> >> >> > >    redundant. It encodes an intention explicit but the intention is
> >> >> > >    in ld aarch64, gold (all ports), and lld (all ports) with no extra option.
> >> >> > >
> >> >> > > IMO, we should do these:
> >> >> > >
> >> >> > > * push this commit
> >> >> > > * treat elf_has_no_copy_on_protected as always true and remove all GNU_PROPERTY_NO_COPY_ON_PROTECTED
> >> >> > >
> >> >> > > Again, I understand that there is concern about protected data symbols
> >> >> > > in shared object.  But as is, nobody uses protected symbols in shared objects.
> >> >> > > My
> >> >> > >
> >> >> > >    // gcc -fpic -shared -fuse-ld=bfd
> >> >> > >    __attribute__((visibility("protected"))) void *foo() {
> >> >> > >      return (void *)foo;
> >> >> > >    }
> >> >> > >
> >> >> > > example indicates that protected future symbol is also broken.
> >> >> >
> >> >> > To get protected symbol to work properly on x86-64, copy relocation on protected
> >> >> > symbols should be disallowed at run-time.
> >> >>
> >> >> Yes that GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will change the
> >> >> glibc warning to an error, but we don't need to hurry making the cases
> >> >> an error.  Since protected symbols do not have performance benefits (in
> >> >> gcc's many ports and GNU ld's x86 port), people avoid using it.  My
> >> >> advise is to just let ld stop producing executables which will trigger
> >> >> glibc warning/error (this has precedent in gold and ld.lld and FreeBSD's
> >> >> adoption of ld.lld means that this goes actually very well).  Projects
> >> >> will gradually fix their builds to enable indirect external access in
> >> >> the rare case they encounter protected symbols in shared objects.  Then
> >> >> in a few years, the glibc warning can naturally upgrade to an error,
> >> >> with possibly a method (e.g. similar to LD_DYNAMIC_WEAK) to downgrade to
> >> >> a warning.  Finally, remove the opt-out method.
> >> >>
> >> >> With this scheme no GNU property is needed.
> >> >
> >> >Then, linker should disallow copy relocation against protected symbols
> >> >and non-canonical reference to canonical protected functions.
> >> >
> >> >Something like this.
> >> >
> >> >
> >> >H.J.
> >> >----
> >> >x86: Disallow invalid relocations against protected symbols
> >> >
> >> >Since glibc 2.36 will issue warnings for copy relocation against
> >> >protected symbols and non-canonical reference to canonical protected
> >> >functions, change the linker to always disallow such relocations.
> >>
> >> Thanks.  When reporting relocation diagnostics, making the condition
> >> stricter by removing elf_has_indirect_extern_access is the right
> >> direction.
> >>
> >>
> >> Your patch alone isn't sufficient to make -fpic -shared below work:
> >
> >My patch is on top of yours.
>
> Thanks.  If you are happy with either, feel free to push them.

I am checking in them now.

Thanks.

> >> __attribute__((visibility("protected"))) void *foo() {
> >>    return (void *)foo;
> >> }
> >>
> >>
> >> >bfd/
> >> >
> >> >       * elf32-i386.c (elf_i386_scan_relocs): Remove check for
> >> >       elf_has_indirect_extern_access.
> >> >       * elf64-x86-64.c (elf_x86_64_scan_relocs): Likewise.
> >> >       (elf_x86_64_relocate_section): Remove check for
> >> >       elf_has_no_copy_on_protected.
> >> >       * elfxx-x86.c (elf_x86_allocate_dynrelocs): Check for building
> >> >       executable instead of elf_has_no_copy_on_protected.
> >> >       (_bfd_x86_elf_adjust_dynamic_symbol): Disallow copy relocation
> >> >       against non-copyable protected symbol.
> >> >       * elfxx-x86.h (SYMBOL_NO_COPYRELOC): Remove check for
> >> >       elf_has_no_copy_on_protected.
> >> >
> >> >ld/
> >> >
> >> >       * testsuite/ld-i386/i386.exp: Expect linker error for PR ld/17709
> >> >       test.
> >> >       * testsuite/ld-i386/pr17709.rd: Removed.
> >> >       * testsuite/ld-i386/pr17709.err: New file.
> >> >       * testsuite/ld-x86-64/pr17709.rd: Removed.
> >> >       * testsuite/ld-x86-64/pr17709.err: New file.
> >> >       * testsuite/ld-x86-64/pr28875-func.err: Updated.
> >> >       * testsuite/ld-x86-64/x86-64.exp: Expect linker error for PR
> >> >       ld/17709 test.  Add tests for function pointer against protected
> >> >       function.
> >> >---
> >> > bfd/elf32-i386.c                        |  3 +--
> >> > bfd/elf64-x86-64.c                      | 10 +++-------
> >> > bfd/elfxx-x86.c                         | 21 +++++++++++++++++++--
> >> > bfd/elfxx-x86.h                         |  3 +--
> >> > ld/testsuite/ld-i386/i386.exp           |  2 +-
> >> > ld/testsuite/ld-i386/pr17709.err        |  2 ++
> >> > ld/testsuite/ld-i386/pr17709.rd         |  4 ----
> >> > ld/testsuite/ld-x86-64/pr17709.err      |  2 ++
> >> > ld/testsuite/ld-x86-64/pr17709.rd       |  4 ----
> >> > ld/testsuite/ld-x86-64/pr28875-func.err |  2 +-
> >> > ld/testsuite/ld-x86-64/x86-64.exp       | 18 +++++++++++++++++-
> >> > 11 files changed, 47 insertions(+), 24 deletions(-)
> >> > create mode 100644 ld/testsuite/ld-i386/pr17709.err
> >> > delete mode 100644 ld/testsuite/ld-i386/pr17709.rd
> >> > create mode 100644 ld/testsuite/ld-x86-64/pr17709.err
> >> > delete mode 100644 ld/testsuite/ld-x86-64/pr17709.rd
> >> >
> >> >diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> >> >index 04a972e646d..cfb0085b245 100644
> >> >--- a/bfd/elf32-i386.c
> >> >+++ b/bfd/elf32-i386.c
> >> >@@ -1812,8 +1812,7 @@ elf_i386_scan_relocs (bfd *abfd,
> >> >                     && h->type == STT_FUNC
> >> >                     && eh->def_protected
> >> >                     && !SYMBOL_DEFINED_NON_SHARED_P (h)
> >> >-                    && h->def_dynamic
> >> >-                    && elf_has_indirect_extern_access (h->root.u.def.section->owner))
> >> >+                    && h->def_dynamic)
> >> >                   {
> >> >                     /* Disallow non-canonical reference to canonical
> >> >                        protected function.  */
> >> >diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> >> >index 3abc68a4127..62a9a22317a 100644
> >> >--- a/bfd/elf64-x86-64.c
> >> >+++ b/bfd/elf64-x86-64.c
> >> >@@ -2255,8 +2255,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
> >> >                     && h->type == STT_FUNC
> >> >                     && eh->def_protected
> >> >                     && !SYMBOL_DEFINED_NON_SHARED_P (h)
> >> >-                    && h->def_dynamic
> >> >-                    && elf_has_indirect_extern_access (h->root.u.def.section->owner))
> >> >+                    && h->def_dynamic)
> >> >                   {
> >> >                     /* Disallow non-canonical reference to canonical
> >> >                        protected function.  */
> >> >@@ -3156,8 +3155,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> >> >              || (h != NULL
> >> >                  && !h->root.linker_def
> >> >                  && !h->root.ldscript_def
> >> >-                 && eh->def_protected
> >> >-                 && elf_has_no_copy_on_protected (h->root.u.def.section->owner)));
> >> >+                 && eh->def_protected));
> >> >
> >> >         if ((input_section->flags & SEC_ALLOC) != 0
> >> >             && (input_section->flags & SEC_READONLY) != 0
> >> >@@ -4097,9 +4095,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> >> >           {
> >> >           case R_X86_64_32S:
> >> >             sec = h->root.u.def.section;
> >> >-            if ((info->nocopyreloc
> >> >-                 || (eh->def_protected
> >> >-                     && elf_has_no_copy_on_protected (h->root.u.def.section->owner)))
> >> >+            if ((info->nocopyreloc || eh->def_protected)
> >> >                 && !(h->root.u.def.section->flags & SEC_CODE))
> >> >               return elf_x86_64_need_pic (info, input_bfd, input_section,
> >> >                                           h, NULL, NULL, howto);
> >> >diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
> >> >index 18f3d335458..7fb972752b3 100644
> >> >--- a/bfd/elfxx-x86.c
> >> >+++ b/bfd/elfxx-x86.c
> >> >@@ -524,8 +524,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
> >> >     {
> >> >       asection *sreloc;
> >> >
> >> >-      if (eh->def_protected
> >> >-        && elf_has_no_copy_on_protected (h->root.u.def.section->owner))
> >> >+      if (eh->def_protected && bfd_link_executable (info))
> >> >       {
> >> >         /* Disallow copy relocation against non-copyable protected
> >> >            symbol.  */
> >> >@@ -3041,6 +3040,24 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
> >> >     }
> >> >   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
> >> >     {
> >> >+      if (eh->def_protected && bfd_link_executable (info))
> >> >+      for (p = h->dyn_relocs; p != NULL; p = p->next)
> >> >+        {
> >> >+          /* Disallow copy relocation against non-copyable protected
> >> >+             symbol.  */
> >> >+          s = p->sec->output_section;
> >> >+          if (s != NULL && (s->flags & SEC_READONLY) != 0)
> >> >+            {
> >> >+              info->callbacks->einfo
> >> >+                /* xgettext:c-format */
> >> >+                (_("%F%P: %pB: copy relocation against non-copyable "
> >> >+                   "protected symbol `%s' in %pB\n"),
> >> >+                 p->sec->owner, h->root.root.string,
> >> >+                 h->root.u.def.section->owner);
> >> >+              return false;
> >> >+            }
> >> >+        }
> >> >+
> >> >       srel->size += htab->sizeof_reloc;
> >> >       h->needs_copy = 1;
> >> >     }
> >> >diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
> >> >index 77fb1ad72bc..7d23893938c 100644
> >> >--- a/bfd/elfxx-x86.h
> >> >+++ b/bfd/elfxx-x86.h
> >> >@@ -135,12 +135,11 @@
> >> >
> >> > /* Should copy relocation be generated for a symbol.  Don't generate
> >> >    copy relocation against a protected symbol defined in a shared
> >> >-   object with GNU_PROPERTY_NO_COPY_ON_PROTECTED.  */
> >> >+   object.  */
> >> > #define SYMBOL_NO_COPYRELOC(INFO, EH) \
> >> >   ((EH)->def_protected \
> >> >    && ((EH)->elf.root.type == bfd_link_hash_defined \
> >> >        || (EH)->elf.root.type == bfd_link_hash_defweak) \
> >> >-   && elf_has_no_copy_on_protected ((EH)->elf.root.u.def.section->owner) \
> >> >    && ((EH)->elf.root.u.def.section->owner->flags & DYNAMIC) != 0 \
> >> >    && ((EH)->elf.root.u.def.section->flags & SEC_CODE) == 0)
> >> >
> >> >diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
> >> >index b4f7de49fd5..0ab9c001336 100644
> >> >--- a/ld/testsuite/ld-i386/i386.exp
> >> >+++ b/ld/testsuite/ld-i386/i386.exp
> >> >@@ -224,7 +224,7 @@ set i386tests {
> >> >      "--32 -mx86-used-note=yes" {pr17709a.s} {} "libpr17709.so"}
> >> >     {"PR ld/17709 (2)" "-melf_i386 tmpdir/libpr17709.so" ""
> >> >      "--32 -mx86-used-note=yes"
> >> >-     {pr17709b.s} {{readelf -r pr17709.rd}} "pr17709"}
> >> >+     {pr17709b.s} {{ld "pr17709.err"}} "pr17709"}
> >> >     {"Build pr19827a.o" "" ""
> >> >      "--32 -mx86-used-note=yes" { pr19827a.S }}
> >> >     {"Build pr19827b.so" "-melf_i386 -shared" ""
> >> >diff --git a/ld/testsuite/ld-i386/pr17709.err b/ld/testsuite/ld-i386/pr17709.err
> >> >new file mode 100644
> >> >index 00000000000..fa6a4bacce3
> >> >--- /dev/null
> >> >+++ b/ld/testsuite/ld-i386/pr17709.err
> >> >@@ -0,0 +1,2 @@
> >> >+.*: tmpdir/pr17709b.o: copy relocation against non-copyable protected symbol `foo' in tmpdir/libpr17709.so
> >> >+#...
> >> >diff --git a/ld/testsuite/ld-i386/pr17709.rd b/ld/testsuite/ld-i386/pr17709.rd
> >> >deleted file mode 100644
> >> >index 8414784b736..00000000000
> >> >--- a/ld/testsuite/ld-i386/pr17709.rd
> >> >+++ /dev/null
> >> >@@ -1,4 +0,0 @@
> >> >-
> >> >-Relocation section '.rel\..*' at offset .* contains 1 entry:
> >> >- Offset     Info    Type            Sym\.Value  Sym\. Name
> >> >-[0-9a-f ]+R_386_COPY +[0-9a-f]+ +foo
> >> >diff --git a/ld/testsuite/ld-x86-64/pr17709.err b/ld/testsuite/ld-x86-64/pr17709.err
> >> >new file mode 100644
> >> >index 00000000000..fa6a4bacce3
> >> >--- /dev/null
> >> >+++ b/ld/testsuite/ld-x86-64/pr17709.err
> >> >@@ -0,0 +1,2 @@
> >> >+.*: tmpdir/pr17709b.o: copy relocation against non-copyable protected symbol `foo' in tmpdir/libpr17709.so
> >> >+#...
> >> >diff --git a/ld/testsuite/ld-x86-64/pr17709.rd b/ld/testsuite/ld-x86-64/pr17709.rd
> >> >deleted file mode 100644
> >> >index beffd3cb34c..00000000000
> >> >--- a/ld/testsuite/ld-x86-64/pr17709.rd
> >> >+++ /dev/null
> >> >@@ -1,4 +0,0 @@
> >> >-
> >> >-Relocation section '.rela\..*' at offset .* contains 1 entry:
> >> >- +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
> >> >-[0-9a-f ]+R_X86_64_COPY+[0-9a-f ]+ +foo \+ 0
> >> >diff --git a/ld/testsuite/ld-x86-64/pr28875-func.err b/ld/testsuite/ld-x86-64/pr28875-func.err
> >> >index 64e961cb3d4..f6f4658deaf 100644
> >> >--- a/ld/testsuite/ld-x86-64/pr28875-func.err
> >> >+++ b/ld/testsuite/ld-x86-64/pr28875-func.err
> >> >@@ -1,2 +1,2 @@
> >> >-.*: tmpdir/protected-func-1b.o: non-canonical reference to canonical protected function `protected_func_1a' in tmpdir/libprotected-func-2b.so
> >> >+.*: tmpdir/protected-func-1b.o: non-canonical reference to canonical protected function `protected_func_1a' in tmpdir/libprotected-func-2..so
> >> > #...
> >> >diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
> >> >index a096c0b9d0f..e6a834a2a61 100644
> >> >--- a/ld/testsuite/ld-x86-64/x86-64.exp
> >> >+++ b/ld/testsuite/ld-x86-64/x86-64.exp
> >> >@@ -177,7 +177,7 @@ set x86_64tests {
> >> >     {"PR ld/17709 (1)" "-melf_x86_64 -shared" ""
> >> >      "--64" {pr17709a.s} {} "libpr17709.so"}
> >> >     {"PR ld/17709 (2)" "-melf_x86_64 tmpdir/libpr17709.so" ""
> >> >-     "--64" {pr17709b.s} {{readelf -rW pr17709.rd}} "pr17709"}
> >> >+     "--64" {pr17709b.s} {{ld "pr17709.err"}} "pr17709"}
> >> >     {"Build pr19827a.o" "" ""
> >> >      "--64" { pr19827a.S }}
> >> >     {"Build pr19827b.so" "-melf_x86_64 -shared" ""
> >> >@@ -1383,6 +1383,22 @@ if { [isnative] && [check_compiler_available] } {
> >> >           {{error_output "pr28875-func.err"}} \
> >> >           "protected-func-2" \
> >> >       ] \
> >> >+      [list \
> >> >+          "Build libprotected-func-2c.so" \
> >> >+          "-shared" \
> >> >+          "-fPIC -Wa,-mx86-used-note=yes" \
> >> >+          { protected-func-2c.c } \
> >> >+          {}  \
> >> >+          "libprotected-func-2c.so" \
> >> >+      ] \
> >> >+      [list \
> >> >+          "Build protected-func-2a without PIE" \
> >> >+          "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-2c.so" \
> >> >+          "$NOPIE_CFLAGS -Wa,-mx86-used-note=yes" \
> >> >+          { protected-func-1b.c } \
> >> >+          {{error_output "pr28875-func.err"}} \
> >> >+          "protected-func-2a" \
> >> >+      ] \
> >> >       [list \
> >> >           "Build libprotected-data-1a.so" \
> >> >           "-shared -z noindirect-extern-access" \
> >> >--
> >> >2.36.1
> >> >
> >
> >
> >
> >--
> >H.J.



-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] x86: Make protected symbols local for -shared
  2022-07-19 15:40                                     ` H.J. Lu
@ 2022-07-25 14:07                                       ` H.J. Lu
  0 siblings, 0 replies; 23+ messages in thread
From: H.J. Lu @ 2022-07-25 14:07 UTC (permalink / raw)
  To: Fangrui Song; +Cc: Binutils

On Tue, Jul 19, 2022 at 8:40 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Mon, Jul 18, 2022 at 9:02 PM Fangrui Song <i@maskray.me> wrote:
> >
> > On 2022-07-18, H.J. Lu wrote:
> > >On Mon, Jul 18, 2022 at 8:13 PM Fangrui Song <i@maskray.me> wrote:
> > >>
> > >> On 2022-07-18, H.J. Lu wrote:
> > >> >On Mon, Jun 27, 2022 at 09:18:27PM -0700, Fangrui Song wrote:
> > >> >> On 2022-06-27, H.J. Lu wrote:
> > >> >> > On Mon, Jun 27, 2022 at 8:44 PM Fangrui Song <i@maskray.me> wrote:
> > >> >> > >
> > >> >> > > On 2022-06-27, H.J. Lu wrote:
> > >> >> > > >On Mon, Jun 27, 2022 at 8:07 PM Fangrui Song <i@maskray.me> wrote:
> > >> >> > > >>
> > >> >> > > >> On 2022-06-27, H.J. Lu wrote:
> > >> >> > > >> >On Mon, Jun 27, 2022 at 11:46 AM Fangrui Song <i@maskray.me> wrote:
> > >> >> > > >> >>
> > >> >> > > >> >> On 2022-06-27, H.J. Lu wrote:
> > >> >> > > >> >> >On Mon, Jun 27, 2022 at 10:53 AM Fangrui Song <i@maskray.me> wrote:
> > >> >> > > >> >> >>
> > >> >> > > >> >> >> On 2022-06-27, H.J. Lu wrote:
> > >> >> > > >> >> >> >On Mon, Jun 27, 2022 at 10:09 AM Fangrui Song <i@maskray.me> wrote:
> > >> >> > > >> >> >> >>
> > >> >> > > >> >> >> >> On 2022-06-27, H.J. Lu wrote:
> > >> >> > > >> >> >> >> >On Sun, Jun 26, 2022 at 12:03 PM Fangrui Song <i@maskray.me> wrote:
> > >> >> > > >> >> >> >> >>
> > >> >> > > >> >> >> >> >> On 2022-06-26, H.J. Lu wrote:
> > >> >> > > >> >> >> >> >> >On Sat, Jun 25, 2022 at 10:44 AM Fangrui Song <i@maskray.me> wrote:
> > >> >> > > >> >> >> >> >> >>
> > >> >> > > >> >> >> >> >> >> Call _bfd_elf_symbol_refs_local_p with local_protected==true.  This has
> > >> >> > > >> >> >> >> >> >> 2 noticeable effects for -shared:
> > >> >> > > >> >> >> >> >> >>
> > >> >> > > >> >> >> >> >> >> * GOT-generating relocations referencing a protected data symbol no
> > >> >> > > >> >> >> >> >> >>   longer lead to a GLOB_DAT (similar to a hidden symbol).
> > >> >> > > >> >> >> >> >> >> * Direct access relocations (e.g. R_X86_64_PC32) no longer has the
> > >> >> > > >> >> >> >> >> >>   confusing diagnostic below.
> > >> >> > > >> >> >> >> >> >>
> > >> >> > > >> >> >> >> >> >>     __attribute__((visibility("protected"))) void *foo() {
> > >> >> > > >> >> >> >> >> >>       return (void *)foo;
> > >> >> > > >> >> >> >> >> >>     }
> > >> >> > > >> >> >> >> >> >>
> > >> >> > > >> >> >> >> >> >>     // gcc -fpic -shared -fuse-ld=bfd
> > >> >> > > >> >> >> >> >> >>     relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
> > >> >> > > >> >> >> >> >> >>
> > >> >> > > >> >> >> >> >> >> The new behavior matches arm, aarch64 (commit
> > >> >> > > >> >> >> >> >> >> 83c325007c5599fa9b60b8d5f7b84842160e1d1b), and powerpc ports, and other
> > >> >> > > >> >> >> >> >> >> linkers: gold and ld.lld.
> > >> >> > > >> >> >> >> >> >>
> > >> >> > > >> >> >> >> >> >> Note: if some code tries to use direct access relocations to take the
> > >> >> > > >> >> >> >> >> >> address of foo, the pointer equality will break, but the error should be
> > >> >> > > >> >> >> >> >> >> reported on the executable link, not on the innocent shared object link.
> > >> >> > > >> >> >> >> >> >> glibc 2.36 will give a warning at relocation resolving time.
> > >> >> > > >> >> >> >> >> >
> > >> >> > > >> >> >> >> >> >It should be controlled by -z [no]indirect-extern-access.   Can you enable
> > >> >> > > >> >> >> >> >> >-z  indirect-extern-access with -shared by default instead?
> > >> >> > > >> >> >> >> >>
> > >> >> > > >> >> >> >> >> If I set `link_info.indirect_extern_access = 1;` in ld/ldmain.c,
> > >> >> > > >> >> >> >> >> bfd/elf-properties.c:654 will create a
> > >> >> > > >> >> >> >> >> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note.
> > >> >> > > >> >> >> >> >> This will probably be unexpected (and check-ld will have 280+ failures).
> > >> >> > > >> >> >> >> >
> > >> >> > > >> >> >> >> >This is normal when the default behavior is changed.  You can pass
> > >> >> > > >> >> >> >> >-z noindirect-extern-access to these testcases.
> > >> >> > > >> >> >> >>
> > >> >> > > >> >> >> >> Adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will be a
> > >> >> > > >> >> >> >> significant behavior change and may unnecessarily break user programs
> > >> >> > > >> >> >> >> (glibc will report an error instead of a warning).
> > >> >> > > >> >> >> >
> > >> >> > > >> >> >> >If glibc reports an error, it is a real bug with unknown consequences
> > >> >> > > >> >> >> >when the copy in the executable is out of sync with the protected
> > >> >> > > >> >> >> >symbol in the shared library,
> > >> >> > > >> >> >>
> > >> >> > > >> >> >> Not necessary.
> > >> >> > > >> >> >>
> > >> >> > > >> >> >> In glibc, GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS has two effects,
> > >> >> > > >> >> >> 1 (copy relocations) and 2 (non-zero value of an undefined function
> > >> >> > > >> >> >> symbol) on
> > >> >> > > >> >> >> https://sourceware.org/pipermail/libc-alpha/2022-June/139552.html
> > >> >> > > >> >> >>
> > >> >> > > >> >> >> 2 does not necessarily cause a problem. In many cases it doesn't as
> > >> >> > > >> >> >> function pointer equality is not an invariant a program relies upon
> > >> >> > > >> >> >> (at least, for many functions, the property is not used). My previous
> > >> >> > > >> >> >> comment has mentioned two cases.
> > >> >> > > >> >> >>
> > >> >> > > >> >> >> 1 likely causes a problem, but technically the shared object can define
> > >> >> > > >> >> >> a protected data symbol without accessing it..
> > >> >> > > >> >> >
> > >> >> > > >> >> >These are unknown consequences.   We don't know what the worst
> > >> >> > > >> >> >cases are.
> > >> >> > > >> >>
> > >> >> > > >> >> They are, just like when a shared object is linked with -Bsymbolic.
> > >> >> > > >> >
> > >> >> > > >> >They have to deal with it since it is done on purpose.
> > >> >> > > >> >
> > >> >> > > >> >> This patch focuses on changing the x86 default to a sane value (matching
> > >> >> > > >> >> aarch64/arm/powerpc64/riscv/etc) and enabling future removal of
> > >> >> > > >> >> `extern_protected_data`.  If you want to switch to
> > >> >> > > >> >> indirect-extern-access default for x86, while I think unnecessary, I will not object.
> > >> >> > > >> >
> > >> >> > > >> >extern_protected_data can be safely removed only when
> > >> >> > > >> >direct access to external symbols are disallowed.   We can't
> > >> >> > > >> >have both ways.
> > >> >> > > >>
> > >> >> > > >> Just define has_no_copy_on_protected to 1 to catch the usage at link
> > >> >> > > >
> > >> >> > > >This is the same as using -z indirect-extern-access on executable.
> > >> >> > > >
> > >> >> > > >> time.  ld's aarch64 port has such an error by default.  gold and ld.lld
> > >> >> > > >> has such an error for a long time now.
> > >> >> > > >>
> > >> >> > > >> We don't need to worry about whether this stricter behavior breaks user
> > >> >> > > >> programs.  As is, protected symbol using GCC+binutils provides no
> > >> >> > > >> benefit.  Programs just avoid protected data symbols.
> > >> >> > > >
> > >> >> > > >Then there should be no problems with
> > >> >> > > >GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
> > >> >> > > >I'd like to disallow copy relocation on protected symbols at run-time
> > >> >> > > >when there are unknown consequences.
> > >> >> > >
> > >> >> > > Enabling GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS for x86 by default
> > >> >> > > has these effects:
> > >> >> > >
> > >> >> > > * 280+ check-ld tests will fail
> > >> >> >
> > >> >> > They should be updated.
> > >> >>
> > >> >> That will be a huge effort and may not be so necessary. See below.
> > >> >>
> > >> >> > > * The GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS note appears
> > >> >> >
> > >> >> > It will disallow copy relocation on protected symbols at run-time.
> > >> >> >
> > >> >> > >    redundant. It encodes an intention explicit but the intention is
> > >> >> > >    in ld aarch64, gold (all ports), and lld (all ports) with no extra option.
> > >> >> > >
> > >> >> > > IMO, we should do these:
> > >> >> > >
> > >> >> > > * push this commit
> > >> >> > > * treat elf_has_no_copy_on_protected as always true and remove all GNU_PROPERTY_NO_COPY_ON_PROTECTED
> > >> >> > >
> > >> >> > > Again, I understand that there is concern about protected data symbols
> > >> >> > > in shared object.  But as is, nobody uses protected symbols in shared objects.
> > >> >> > > My
> > >> >> > >
> > >> >> > >    // gcc -fpic -shared -fuse-ld=bfd
> > >> >> > >    __attribute__((visibility("protected"))) void *foo() {
> > >> >> > >      return (void *)foo;
> > >> >> > >    }
> > >> >> > >
> > >> >> > > example indicates that protected future symbol is also broken.
> > >> >> >
> > >> >> > To get protected symbol to work properly on x86-64, copy relocation on protected
> > >> >> > symbols should be disallowed at run-time.
> > >> >>
> > >> >> Yes that GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS will change the
> > >> >> glibc warning to an error, but we don't need to hurry making the cases
> > >> >> an error.  Since protected symbols do not have performance benefits (in
> > >> >> gcc's many ports and GNU ld's x86 port), people avoid using it.  My
> > >> >> advise is to just let ld stop producing executables which will trigger
> > >> >> glibc warning/error (this has precedent in gold and ld.lld and FreeBSD's
> > >> >> adoption of ld.lld means that this goes actually very well).  Projects
> > >> >> will gradually fix their builds to enable indirect external access in
> > >> >> the rare case they encounter protected symbols in shared objects.  Then
> > >> >> in a few years, the glibc warning can naturally upgrade to an error,
> > >> >> with possibly a method (e.g. similar to LD_DYNAMIC_WEAK) to downgrade to
> > >> >> a warning.  Finally, remove the opt-out method.
> > >> >>
> > >> >> With this scheme no GNU property is needed.
> > >> >
> > >> >Then, linker should disallow copy relocation against protected symbols
> > >> >and non-canonical reference to canonical protected functions.
> > >> >
> > >> >Something like this.
> > >> >
> > >> >
> > >> >H.J.
> > >> >----
> > >> >x86: Disallow invalid relocations against protected symbols
> > >> >
> > >> >Since glibc 2.36 will issue warnings for copy relocation against
> > >> >protected symbols and non-canonical reference to canonical protected
> > >> >functions, change the linker to always disallow such relocations.
> > >>
> > >> Thanks.  When reporting relocation diagnostics, making the condition
> > >> stricter by removing elf_has_indirect_extern_access is the right
> > >> direction.
> > >>
> > >>
> > >> Your patch alone isn't sufficient to make -fpic -shared below work:
> > >
> > >My patch is on top of yours.
> >
> > Thanks.  If you are happy with either, feel free to push them.
>
> I am checking in them now.

I am backporting these 2 patches to 2.39 branch.

> Thanks.
>
> > >> __attribute__((visibility("protected"))) void *foo() {
> > >>    return (void *)foo;
> > >> }
> > >>
> > >>
> > >> >bfd/
> > >> >
> > >> >       * elf32-i386.c (elf_i386_scan_relocs): Remove check for
> > >> >       elf_has_indirect_extern_access.
> > >> >       * elf64-x86-64.c (elf_x86_64_scan_relocs): Likewise.
> > >> >       (elf_x86_64_relocate_section): Remove check for
> > >> >       elf_has_no_copy_on_protected.
> > >> >       * elfxx-x86.c (elf_x86_allocate_dynrelocs): Check for building
> > >> >       executable instead of elf_has_no_copy_on_protected.
> > >> >       (_bfd_x86_elf_adjust_dynamic_symbol): Disallow copy relocation
> > >> >       against non-copyable protected symbol.
> > >> >       * elfxx-x86.h (SYMBOL_NO_COPYRELOC): Remove check for
> > >> >       elf_has_no_copy_on_protected.
> > >> >
> > >> >ld/
> > >> >
> > >> >       * testsuite/ld-i386/i386.exp: Expect linker error for PR ld/17709
> > >> >       test.
> > >> >       * testsuite/ld-i386/pr17709.rd: Removed.
> > >> >       * testsuite/ld-i386/pr17709.err: New file.
> > >> >       * testsuite/ld-x86-64/pr17709.rd: Removed.
> > >> >       * testsuite/ld-x86-64/pr17709.err: New file.
> > >> >       * testsuite/ld-x86-64/pr28875-func.err: Updated.
> > >> >       * testsuite/ld-x86-64/x86-64.exp: Expect linker error for PR
> > >> >       ld/17709 test.  Add tests for function pointer against protected
> > >> >       function.
> > >> >---
> > >> > bfd/elf32-i386.c                        |  3 +--
> > >> > bfd/elf64-x86-64.c                      | 10 +++-------
> > >> > bfd/elfxx-x86.c                         | 21 +++++++++++++++++++--
> > >> > bfd/elfxx-x86.h                         |  3 +--
> > >> > ld/testsuite/ld-i386/i386.exp           |  2 +-
> > >> > ld/testsuite/ld-i386/pr17709.err        |  2 ++
> > >> > ld/testsuite/ld-i386/pr17709.rd         |  4 ----
> > >> > ld/testsuite/ld-x86-64/pr17709.err      |  2 ++
> > >> > ld/testsuite/ld-x86-64/pr17709.rd       |  4 ----
> > >> > ld/testsuite/ld-x86-64/pr28875-func.err |  2 +-
> > >> > ld/testsuite/ld-x86-64/x86-64.exp       | 18 +++++++++++++++++-
> > >> > 11 files changed, 47 insertions(+), 24 deletions(-)
> > >> > create mode 100644 ld/testsuite/ld-i386/pr17709.err
> > >> > delete mode 100644 ld/testsuite/ld-i386/pr17709.rd
> > >> > create mode 100644 ld/testsuite/ld-x86-64/pr17709.err
> > >> > delete mode 100644 ld/testsuite/ld-x86-64/pr17709.rd
> > >> >
> > >> >diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> > >> >index 04a972e646d..cfb0085b245 100644
> > >> >--- a/bfd/elf32-i386.c
> > >> >+++ b/bfd/elf32-i386.c
> > >> >@@ -1812,8 +1812,7 @@ elf_i386_scan_relocs (bfd *abfd,
> > >> >                     && h->type == STT_FUNC
> > >> >                     && eh->def_protected
> > >> >                     && !SYMBOL_DEFINED_NON_SHARED_P (h)
> > >> >-                    && h->def_dynamic
> > >> >-                    && elf_has_indirect_extern_access (h->root.u.def.section->owner))
> > >> >+                    && h->def_dynamic)
> > >> >                   {
> > >> >                     /* Disallow non-canonical reference to canonical
> > >> >                        protected function.  */
> > >> >diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> > >> >index 3abc68a4127..62a9a22317a 100644
> > >> >--- a/bfd/elf64-x86-64.c
> > >> >+++ b/bfd/elf64-x86-64.c
> > >> >@@ -2255,8 +2255,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
> > >> >                     && h->type == STT_FUNC
> > >> >                     && eh->def_protected
> > >> >                     && !SYMBOL_DEFINED_NON_SHARED_P (h)
> > >> >-                    && h->def_dynamic
> > >> >-                    && elf_has_indirect_extern_access (h->root.u.def.section->owner))
> > >> >+                    && h->def_dynamic)
> > >> >                   {
> > >> >                     /* Disallow non-canonical reference to canonical
> > >> >                        protected function.  */
> > >> >@@ -3156,8 +3155,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> > >> >              || (h != NULL
> > >> >                  && !h->root.linker_def
> > >> >                  && !h->root.ldscript_def
> > >> >-                 && eh->def_protected
> > >> >-                 && elf_has_no_copy_on_protected (h->root.u.def.section->owner)));
> > >> >+                 && eh->def_protected));
> > >> >
> > >> >         if ((input_section->flags & SEC_ALLOC) != 0
> > >> >             && (input_section->flags & SEC_READONLY) != 0
> > >> >@@ -4097,9 +4095,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
> > >> >           {
> > >> >           case R_X86_64_32S:
> > >> >             sec = h->root.u.def.section;
> > >> >-            if ((info->nocopyreloc
> > >> >-                 || (eh->def_protected
> > >> >-                     && elf_has_no_copy_on_protected (h->root.u.def.section->owner)))
> > >> >+            if ((info->nocopyreloc || eh->def_protected)
> > >> >                 && !(h->root.u.def.section->flags & SEC_CODE))
> > >> >               return elf_x86_64_need_pic (info, input_bfd, input_section,
> > >> >                                           h, NULL, NULL, howto);
> > >> >diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
> > >> >index 18f3d335458..7fb972752b3 100644
> > >> >--- a/bfd/elfxx-x86.c
> > >> >+++ b/bfd/elfxx-x86.c
> > >> >@@ -524,8 +524,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
> > >> >     {
> > >> >       asection *sreloc;
> > >> >
> > >> >-      if (eh->def_protected
> > >> >-        && elf_has_no_copy_on_protected (h->root.u.def.section->owner))
> > >> >+      if (eh->def_protected && bfd_link_executable (info))
> > >> >       {
> > >> >         /* Disallow copy relocation against non-copyable protected
> > >> >            symbol.  */
> > >> >@@ -3041,6 +3040,24 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
> > >> >     }
> > >> >   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
> > >> >     {
> > >> >+      if (eh->def_protected && bfd_link_executable (info))
> > >> >+      for (p = h->dyn_relocs; p != NULL; p = p->next)
> > >> >+        {
> > >> >+          /* Disallow copy relocation against non-copyable protected
> > >> >+             symbol.  */
> > >> >+          s = p->sec->output_section;
> > >> >+          if (s != NULL && (s->flags & SEC_READONLY) != 0)
> > >> >+            {
> > >> >+              info->callbacks->einfo
> > >> >+                /* xgettext:c-format */
> > >> >+                (_("%F%P: %pB: copy relocation against non-copyable "
> > >> >+                   "protected symbol `%s' in %pB\n"),
> > >> >+                 p->sec->owner, h->root.root.string,
> > >> >+                 h->root.u.def.section->owner);
> > >> >+              return false;
> > >> >+            }
> > >> >+        }
> > >> >+
> > >> >       srel->size += htab->sizeof_reloc;
> > >> >       h->needs_copy = 1;
> > >> >     }
> > >> >diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
> > >> >index 77fb1ad72bc..7d23893938c 100644
> > >> >--- a/bfd/elfxx-x86.h
> > >> >+++ b/bfd/elfxx-x86.h
> > >> >@@ -135,12 +135,11 @@
> > >> >
> > >> > /* Should copy relocation be generated for a symbol.  Don't generate
> > >> >    copy relocation against a protected symbol defined in a shared
> > >> >-   object with GNU_PROPERTY_NO_COPY_ON_PROTECTED.  */
> > >> >+   object.  */
> > >> > #define SYMBOL_NO_COPYRELOC(INFO, EH) \
> > >> >   ((EH)->def_protected \
> > >> >    && ((EH)->elf.root.type == bfd_link_hash_defined \
> > >> >        || (EH)->elf.root.type == bfd_link_hash_defweak) \
> > >> >-   && elf_has_no_copy_on_protected ((EH)->elf.root.u.def.section->owner) \
> > >> >    && ((EH)->elf.root.u.def.section->owner->flags & DYNAMIC) != 0 \
> > >> >    && ((EH)->elf.root.u.def.section->flags & SEC_CODE) == 0)
> > >> >
> > >> >diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
> > >> >index b4f7de49fd5..0ab9c001336 100644
> > >> >--- a/ld/testsuite/ld-i386/i386.exp
> > >> >+++ b/ld/testsuite/ld-i386/i386.exp
> > >> >@@ -224,7 +224,7 @@ set i386tests {
> > >> >      "--32 -mx86-used-note=yes" {pr17709a.s} {} "libpr17709.so"}
> > >> >     {"PR ld/17709 (2)" "-melf_i386 tmpdir/libpr17709.so" ""
> > >> >      "--32 -mx86-used-note=yes"
> > >> >-     {pr17709b.s} {{readelf -r pr17709.rd}} "pr17709"}
> > >> >+     {pr17709b.s} {{ld "pr17709.err"}} "pr17709"}
> > >> >     {"Build pr19827a.o" "" ""
> > >> >      "--32 -mx86-used-note=yes" { pr19827a.S }}
> > >> >     {"Build pr19827b.so" "-melf_i386 -shared" ""
> > >> >diff --git a/ld/testsuite/ld-i386/pr17709.err b/ld/testsuite/ld-i386/pr17709.err
> > >> >new file mode 100644
> > >> >index 00000000000..fa6a4bacce3
> > >> >--- /dev/null
> > >> >+++ b/ld/testsuite/ld-i386/pr17709.err
> > >> >@@ -0,0 +1,2 @@
> > >> >+.*: tmpdir/pr17709b.o: copy relocation against non-copyable protected symbol `foo' in tmpdir/libpr17709.so
> > >> >+#...
> > >> >diff --git a/ld/testsuite/ld-i386/pr17709.rd b/ld/testsuite/ld-i386/pr17709.rd
> > >> >deleted file mode 100644
> > >> >index 8414784b736..00000000000
> > >> >--- a/ld/testsuite/ld-i386/pr17709.rd
> > >> >+++ /dev/null
> > >> >@@ -1,4 +0,0 @@
> > >> >-
> > >> >-Relocation section '.rel\..*' at offset .* contains 1 entry:
> > >> >- Offset     Info    Type            Sym\.Value  Sym\. Name
> > >> >-[0-9a-f ]+R_386_COPY +[0-9a-f]+ +foo
> > >> >diff --git a/ld/testsuite/ld-x86-64/pr17709.err b/ld/testsuite/ld-x86-64/pr17709.err
> > >> >new file mode 100644
> > >> >index 00000000000..fa6a4bacce3
> > >> >--- /dev/null
> > >> >+++ b/ld/testsuite/ld-x86-64/pr17709.err
> > >> >@@ -0,0 +1,2 @@
> > >> >+.*: tmpdir/pr17709b.o: copy relocation against non-copyable protected symbol `foo' in tmpdir/libpr17709.so
> > >> >+#...
> > >> >diff --git a/ld/testsuite/ld-x86-64/pr17709.rd b/ld/testsuite/ld-x86-64/pr17709.rd
> > >> >deleted file mode 100644
> > >> >index beffd3cb34c..00000000000
> > >> >--- a/ld/testsuite/ld-x86-64/pr17709.rd
> > >> >+++ /dev/null
> > >> >@@ -1,4 +0,0 @@
> > >> >-
> > >> >-Relocation section '.rela\..*' at offset .* contains 1 entry:
> > >> >- +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
> > >> >-[0-9a-f ]+R_X86_64_COPY+[0-9a-f ]+ +foo \+ 0
> > >> >diff --git a/ld/testsuite/ld-x86-64/pr28875-func.err b/ld/testsuite/ld-x86-64/pr28875-func.err
> > >> >index 64e961cb3d4..f6f4658deaf 100644
> > >> >--- a/ld/testsuite/ld-x86-64/pr28875-func.err
> > >> >+++ b/ld/testsuite/ld-x86-64/pr28875-func.err
> > >> >@@ -1,2 +1,2 @@
> > >> >-.*: tmpdir/protected-func-1b.o: non-canonical reference to canonical protected function `protected_func_1a' in tmpdir/libprotected-func-2b.so
> > >> >+.*: tmpdir/protected-func-1b.o: non-canonical reference to canonical protected function `protected_func_1a' in tmpdir/libprotected-func-2..so
> > >> > #...
> > >> >diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
> > >> >index a096c0b9d0f..e6a834a2a61 100644
> > >> >--- a/ld/testsuite/ld-x86-64/x86-64.exp
> > >> >+++ b/ld/testsuite/ld-x86-64/x86-64.exp
> > >> >@@ -177,7 +177,7 @@ set x86_64tests {
> > >> >     {"PR ld/17709 (1)" "-melf_x86_64 -shared" ""
> > >> >      "--64" {pr17709a.s} {} "libpr17709.so"}
> > >> >     {"PR ld/17709 (2)" "-melf_x86_64 tmpdir/libpr17709.so" ""
> > >> >-     "--64" {pr17709b.s} {{readelf -rW pr17709.rd}} "pr17709"}
> > >> >+     "--64" {pr17709b.s} {{ld "pr17709.err"}} "pr17709"}
> > >> >     {"Build pr19827a.o" "" ""
> > >> >      "--64" { pr19827a.S }}
> > >> >     {"Build pr19827b.so" "-melf_x86_64 -shared" ""
> > >> >@@ -1383,6 +1383,22 @@ if { [isnative] && [check_compiler_available] } {
> > >> >           {{error_output "pr28875-func.err"}} \
> > >> >           "protected-func-2" \
> > >> >       ] \
> > >> >+      [list \
> > >> >+          "Build libprotected-func-2c.so" \
> > >> >+          "-shared" \
> > >> >+          "-fPIC -Wa,-mx86-used-note=yes" \
> > >> >+          { protected-func-2c.c } \
> > >> >+          {}  \
> > >> >+          "libprotected-func-2c.so" \
> > >> >+      ] \
> > >> >+      [list \
> > >> >+          "Build protected-func-2a without PIE" \
> > >> >+          "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-2c.so" \
> > >> >+          "$NOPIE_CFLAGS -Wa,-mx86-used-note=yes" \
> > >> >+          { protected-func-1b.c } \
> > >> >+          {{error_output "pr28875-func.err"}} \
> > >> >+          "protected-func-2a" \
> > >> >+      ] \
> > >> >       [list \
> > >> >           "Build libprotected-data-1a.so" \
> > >> >           "-shared -z noindirect-extern-access" \
> > >> >--
> > >> >2.36.1
> > >> >
> > >
> > >
> > >
> > >--
> > >H.J.
>
>
>
> --
> H.J.



-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2022-07-25 14:07 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-25 17:44 [PATCH] x86: Make protected symbols local for -shared Fangrui Song
2022-06-26 18:13 ` H.J. Lu
2022-06-26 19:03   ` Fangrui Song
2022-06-26 19:07     ` Fangrui Song
2022-06-27 13:30       ` H.J. Lu
2022-06-27 13:24     ` H.J. Lu
2022-06-27 17:09       ` Fangrui Song
2022-06-27 17:43         ` H.J. Lu
2022-06-27 17:53           ` Fangrui Song
2022-06-27 18:26             ` H.J. Lu
2022-06-27 18:46               ` Fangrui Song
2022-06-27 18:57                 ` H.J. Lu
2022-06-28  3:07                   ` Fangrui Song
2022-06-28  3:24                     ` H.J. Lu
2022-06-28  3:43                       ` Fangrui Song
2022-06-28  3:51                         ` H.J. Lu
2022-06-28  4:18                           ` Fangrui Song
2022-07-19  1:44                             ` H.J. Lu
2022-07-19  3:13                               ` Fangrui Song
2022-07-19  3:38                                 ` H.J. Lu
2022-07-19  4:02                                   ` Fangrui Song
2022-07-19 15:40                                     ` H.J. Lu
2022-07-25 14:07                                       ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).