about summary refs log tree commit diff
path: root/sysdeps/x86_64/dl-machine.h
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2016-10-28 09:11:55 -0700
committerH.J. Lu <hjl.tools@gmail.com>2016-10-28 09:12:15 -0700
commit0e6d3adc60d8073397af6a320e594d98d7fbedde (patch)
tree2578786c88497b0e932da9f4d03abefa1a73e20f /sysdeps/x86_64/dl-machine.h
parent6b1df8b27f7c48d3933b152c0edc9493b199df84 (diff)
downloadglibc-0e6d3adc60d8073397af6a320e594d98d7fbedde.tar.gz
glibc-0e6d3adc60d8073397af6a320e594d98d7fbedde.tar.xz
glibc-0e6d3adc60d8073397af6a320e594d98d7fbedde.zip
Check IFUNC definition in unrelocated shared library [BZ #20019]
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.
Diffstat (limited to 'sysdeps/x86_64/dl-machine.h')
-rw-r--r--sysdeps/x86_64/dl-machine.h18
1 files changed, 17 insertions, 1 deletions
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index c0f0fa16a2..5c021dcf99 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -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)
 	{