x86: Disallow invalid relocations against protected symbols
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 19 Jul 2022 01:24:26 +0000 (18:24 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 19 Jul 2022 15:41:52 +0000 (08:41 -0700)
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
bfd/elf64-x86-64.c
bfd/elfxx-x86.c
bfd/elfxx-x86.h
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/pr17709.err [new file with mode: 0644]
ld/testsuite/ld-i386/pr17709.rd [deleted file]
ld/testsuite/ld-x86-64/pr17709.err [new file with mode: 0644]
ld/testsuite/ld-x86-64/pr17709.rd [deleted file]
ld/testsuite/ld-x86-64/pr28875-func.err
ld/testsuite/ld-x86-64/x86-64.exp

index 04a972e646de16af16bdd7a1c72eb1958a0f5a3d..cfb0085b245a6535c20609c1fb2a3d6264dcd9b0 100644 (file)
@@ -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.  */
index 3abc68a41275ccae07166609b9d907c004761fbd..62a9a22317a13799324516156dc9be23891b32bd 100644 (file)
@@ -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);
index 18f3d33545842af6e25302f42b45e7e1ce01d6b9..7fb972752b347617137548da1c2764700d90a61e 100644 (file)
@@ -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;
     }
index 77fb1ad72bc284cdac29d2e9bae3ad53ee60f7cf..7d23893938c271326166d9cbcc793156d0fb508b 100644 (file)
 
 /* 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)
 
index b4f7de49fd57116a64aec4e7dabde7f2a224239c..0ab9c001336d783ed470a7da6367bb4f27f91410 100644 (file)
@@ -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 (file)
index 0000000..fa6a4ba
--- /dev/null
@@ -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 (file)
index 8414784..0000000
+++ /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 (file)
index 0000000..fa6a4ba
--- /dev/null
@@ -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 (file)
index beffd3c..0000000
+++ /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
index 64e961cb3d4771fe726603f2ab3b180dbff9ad05..f6f4658deafcf7ffba87a9147e678c307e30bfae 100644 (file)
@@ -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
 #...
index a096c0b9d0f76d52e274cd8a8fc30f3709a932a7..e6a834a2a61b0a63789e260ce56d10c177aa7ba9 100644 (file)
@@ -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" \