]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
hppa: Fix bind-now audit (BZ #28857)
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 4 Feb 2022 18:54:59 +0000 (15:54 -0300)
committerCarlos O'Donell <carlos@redhat.com>
Tue, 12 Apr 2022 17:33:17 +0000 (13:33 -0400)
On hppa, a function pointer returned by la_symbind is actually a function
descriptor has the plabel bit set (bit 30).  This must be cleared to get
the actual address of the descriptor.  If the descriptor has been bound,
the first word of the descriptor is the physical address of theA function,
otherwise, the first word of the descriptor points to a trampoline in the
PLT.

This patch also adds a workaround on tests because on hppa (and it seems
to be the only ABI I have see it), some shared library adds a dynamic PLT
relocation to am empty symbol name:

$ readelf -r elf/tst-audit25mod1.so
[...]
Relocation section '.rela.plt' at offset 0x464 contains 6 entries:
 Offset     Info    Type            Sym.Value  Sym. Name + Addend
00002008  00000081 R_PARISC_IPLT                508
[...]

It breaks some assumptions on the test, where a symbol with an empty
name ("") is passed on la_symbind.

Checked on x86_64-linux-gnu and hppa-linux-gnu.

(cherry picked from commit 9e94f57484a2aba0fe67ea2059b5843f651887c2)

elf/Makefile
elf/dl-audit.c
elf/tst-auditmod24a.c
elf/tst-auditmod24d.c
elf/tst-auditmod25.c
sysdeps/hppa/dl-lookupcfg.h

index 38e5793f35b497c67b4d0c7de4e1798f71d46876..fe954374c97608e47045d852d80d4e48d56c8c44 100644 (file)
@@ -2072,7 +2072,7 @@ $(objpfx)tst-audit24c.out: $(objpfx)tst-auditmod24c.so
 $(objpfx)tst-audit24c: $(objpfx)tst-audit24amod1.so \
                       $(objpfx)tst-audit24amod2.so
 tst-audit24c-ENV = LD_BIND_NOW=1 LD_AUDIT=$(objpfx)tst-auditmod24c.so
-LDFLAGS-tst-audit24b = -Wl,-z,lazy
+LDFLAGS-tst-audit24c = -Wl,-z,lazy
 
 $(objpfx)tst-audit24d.out: $(objpfx)tst-auditmod24d.so
 $(objpfx)tst-audit24d: $(objpfx)tst-audit24dmod1.so \
index 72a50717ef60a3577f20da203b8115645e383fc3..ec9b032eae37c103377a6cdec84b893a416ea464 100644 (file)
@@ -257,7 +257,8 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
       reloc_result->flags = flags;
     }
 
-  DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value);
+  if (flags & LA_SYMB_ALTVALUE)
+    DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value);
 }
 
 void
index d8e88f3984af1707aaec3ba7ae5a5f1f7c69c753..3075dfae2fd3d288baf2f91ab47481619961986e 100644 (file)
@@ -110,5 +110,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
       return sym->st_value;
     }
 
-  abort ();
+  if (symname[0] != '\0')
+    abort ();
+  return sym->st_value;
 }
index 8c803ecc0a48f21b3270d69533c23662b691711e..badc6be451ee03574203b1183289c12de0335fc9 100644 (file)
@@ -116,5 +116,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
        }
     }
 
-  abort ();
+  if (symname[0] != '\0')
+    abort ();
+  return sym->st_value;
 }
index 526f5c54bc2c3b8c4b1b34700c26dc7cbab77e2c..20640a8daf346b5f56819509e04b4c52eeb92a4c 100644 (file)
@@ -72,7 +72,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
              unsigned int *flags, const char *symname)
 #endif
 {
-  if (*refcook != -1 && *defcook != -1)
+  if (*refcook != -1 && *defcook != -1 && symname[0] != '\0')
     fprintf (stderr, "la_symbind: %s %u\n", symname,
             *flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0);
   return sym->st_value;
index f4f00714fa158e18372759aa63b8f18b270e9b9e..92fd0b7c844713cea2d95f72ad94cea7586fb3a7 100644 (file)
@@ -80,7 +80,9 @@ void attribute_hidden _dl_unmap (struct link_map *map);
 /* Extract the code address from a fixup value */
 #define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip)
 #define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value))
-#define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr))
+/* Clear the plabel bit to get the actual address of the descriptor.  */
+#define DL_FIXUP_ADDR_VALUE(addr) \
+  (*(DL_FIXUP_VALUE_TYPE *) ((uintptr_t) (addr) & ~2))
 #define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
-#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
-  (*value) = *(struct fdesc *) (st_value)
+#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value)     \
+  *(value) = *(DL_FIXUP_VALUE_TYPE *) ((uintptr_t) (new_value) & ~2)