]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Check IFUNC definition in unrelocated shared library [BZ #20019]
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 28 Oct 2016 16:11:55 +0000 (09:11 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 28 Oct 2016 16:12:15 +0000 (09:12 -0700)
Calling an IFUNC function defined in unrelocated shared library may
lead to segfault.  This patch issues an error message to request
relinking the shared library if it references IFUNC function defined
in the unrelocated shared library.

[BZ #20019]
* sysdeps/i386/dl-machine.h (elf_machine_rel): Check IFUNC
definition in unrelocated shared library.
* sysdeps/x86_64/dl-machine.h (elf_machine_rela): Likewise.

ChangeLog
sysdeps/i386/dl-machine.h
sysdeps/x86_64/dl-machine.h

index b5626ed5cad90ebd2eeb4c4ab839faed5101104d..995720ec690340ad931e34d4bdb964e6d4e1ec20 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2016-10-28  H.J. Lu  <hongjiu.lu@intel.com>
+
+       [BZ #20019]
+       * sysdeps/i386/dl-machine.h (elf_machine_rel): Check IFUNC
+       definition in unrelocated shared library.
+       * sysdeps/x86_64/dl-machine.h (elf_machine_rela): Likewise.
+
 2016-10-28  Florian Weimer  <fweimer@redhat.com>
 
        [BZ #20729]
index 4e3968a8aaa258da1d4f42027ec241883e055168..e5ad0c513d237c5369da1c01714977463046793e 100644 (file)
@@ -321,7 +321,23 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
                               0)
          && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
          && __builtin_expect (!skip_ifunc, 1))
-       value = ((Elf32_Addr (*) (void)) value) ();
+       {
+# ifndef RTLD_BOOTSTRAP
+         if (sym_map != map
+             && sym_map->l_type != lt_executable
+             && !sym_map->l_relocated)
+           {
+             const char *strtab
+               = (const char *) D_PTR (map, l_info[DT_STRTAB]);
+             _dl_fatal_printf ("\
+%s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
+                               RTLD_PROGNAME, map->l_name,
+                               sym_map->l_name,
+                               strtab + refsym->st_name);
+           }
+# endif
+         value = ((Elf32_Addr (*) (void)) value) ();
+       }
 
       switch (r_type)
        {
index c0f0fa16a23b99ecd314d6186409946f72ee319f..5c021dcf9921b74ec92edf982a301863a3d994a1 100644 (file)
@@ -331,7 +331,23 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
                               0)
          && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
          && __builtin_expect (!skip_ifunc, 1))
-       value = ((ElfW(Addr) (*) (void)) value) ();
+       {
+# ifndef RTLD_BOOTSTRAP
+         if (sym_map != map
+             && sym_map->l_type != lt_executable
+             && !sym_map->l_relocated)
+           {
+             const char *strtab
+               = (const char *) D_PTR (map, l_info[DT_STRTAB]);
+             _dl_fatal_printf ("\
+%s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
+                               RTLD_PROGNAME, map->l_name,
+                               sym_map->l_name,
+                               strtab + refsym->st_name);
+           }
+# endif
+         value = ((ElfW(Addr) (*) (void)) value) ();
+       }
 
       switch (r_type)
        {