]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
x86: Check IFUNC definition in unrelocated executable [BZ #20019]
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 28 Dec 2020 13:28:49 +0000 (05:28 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 4 Jan 2021 20:01:01 +0000 (12:01 -0800)
Calling an IFUNC function defined in unrelocated executable also leads to
segfault.  Issue a fatal error message when calling IFUNC function defined
in the unrelocated executable from a shared library.

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

index 50960605e67fa8da85d13183ab7110389ce89d01..23e9cc3bfbb2cde52a2b2f70ffecedca8e5ec7f2 100644 (file)
@@ -337,16 +337,22 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
        {
 # 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_error_printf ("\
+             if (sym_map->l_type == lt_executable)
+               _dl_fatal_printf ("\
+%s: IFUNC symbol '%s' referenced in '%s' is defined in the executable \
+and creates an unsatisfiable circular dependency.\n",
+                                 RTLD_PROGNAME, strtab + refsym->st_name,
+                                 map->l_name);
+             else
+               _dl_error_printf ("\
 %s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
-                               RTLD_PROGNAME, map->l_name,
-                               sym_map->l_name,
-                               strtab + refsym->st_name);
+                                 RTLD_PROGNAME, map->l_name,
+                                 sym_map->l_name,
+                                 strtab + refsym->st_name);
            }
 # endif
          value = ((Elf32_Addr (*) (void)) value) ();
index f582be53200a09a55c58db7a4a2d020075cf5aee..103eee6c3ff6e1ac88a6415d2f74ee1800483ded 100644 (file)
@@ -314,16 +314,22 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
        {
 # 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_error_printf ("\
+             if (sym_map->l_type == lt_executable)
+               _dl_fatal_printf ("\
+%s: IFUNC symbol '%s' referenced in '%s' is defined in the executable \
+and creates an unsatisfiable circular dependency.\n",
+                                 RTLD_PROGNAME, strtab + refsym->st_name,
+                                 map->l_name);
+             else
+               _dl_error_printf ("\
 %s: Relink `%s' with `%s' for IFUNC symbol `%s'\n",
-                               RTLD_PROGNAME, map->l_name,
-                               sym_map->l_name,
-                               strtab + refsym->st_name);
+                                 RTLD_PROGNAME, map->l_name,
+                                 sym_map->l_name,
+                                 strtab + refsym->st_name);
            }
 # endif
          value = ((ElfW(Addr) (*) (void)) value) ();