From patchwork Tue Oct 4 18:45:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lu, Hongjiu" X-Patchwork-Id: 16250 Received: (qmail 100140 invoked by alias); 4 Oct 2016 18:45:22 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 100126 invoked by uid 89); 4 Oct 2016 18:45:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.3 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, NO_DNS_FOR_FROM, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=Hx-languages-length:2342 X-HELO: mga14.intel.com X-ExtLoop1: 1 Date: Tue, 4 Oct 2016 11:45:16 -0700 From: "H.J. Lu" To: GNU C Library Subject: [PATCH 1/2] Check IFUNC definition in unrelocated shared library [BZ #20019] Message-ID: <20161004184516.GA27454@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.7.0 (2016-08-17) 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. Tested on i686 and x86-64. OK for master? H.J. --- [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. --- sysdeps/i386/dl-machine.h | 18 +++++++++++++++++- sysdeps/x86_64/dl-machine.h | 18 +++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 4e3968a..e5ad0c5 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -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) { diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h index c0f0fa1..5c021dc 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) {