This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.21-230-g19a6a3a


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  19a6a3acd10e04fc3aba8941b44918acc7003aa2 (commit)
      from  efd5b641dd793fe385e1685047f2c82f4811076c (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=19a6a3acd10e04fc3aba8941b44918acc7003aa2

commit 19a6a3acd10e04fc3aba8941b44918acc7003aa2
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Mar 26 12:30:45 2015 +1030

    Harden powerpc64 elf_machine_fixup_plt
    
    IFUNC is difficult to correctly implement on any target needing a GOT
    to support position independent code, due to the dependency on order
    of dynamic relocations.  ld.so should be changed to apply IFUNC
    relocations last, globally, because without that it is actually
    impossible to write an IFUNC resolver in C that works in all
    situations.  Case in point, vfork in libpthread.so is an IFUNC with
    the resolver returning &__libc_vfork.  (system and fork are similar.)
    If another shared library, libA say, uses vfork then it is quite
    possible that libpthread.so hasn't been dynamically relocated before
    the unfortunate libA is dynamically relocated.  In that case the GOT
    entry for &__libc_vfork is still zero, so the IFUNC resolver returns
    NULL.  LD_BIND_NOW=1 results in libA PLT dynamic relocations being
    applied using this NULL value and ld.so segfaults.
    
    This patch hardens ld.so to not segfault on a NULL from an IFUNC
    resolver.  It also fixes a problem with undefined weak.  If you leave
    the plt entry as-is for undefined weak then if the entry is ever
    called it will loop in ld.so rather than segfaulting.
    
    	* sysdeps/powerpc/powerpc64/dl-machine.h (elf_machine_fixup_plt):
    	Don't segfault if ifunc resolver returns a NULL.  Do set plt to
    	zero for undefined weak.
    	(elf_machine_plt_conflict): Similarly.

diff --git a/ChangeLog b/ChangeLog
index 8e159ac..38ac2ac 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2015-03-26  Alan Modra  <amodra@gmail.com>
+
+	* sysdeps/powerpc/powerpc64/dl-machine.h (elf_machine_fixup_plt):
+	Don't segfault if ifunc resolver returns a NULL.  Do set plt to
+	zero for undefined weak.
+	(elf_machine_plt_conflict): Similarly.
+
 2015-03-25  Joseph Myers  <joseph@codesourcery.com>
 
 	* math/auto-libm-test-in: Add more tests of acosh, asinh and
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
index 55ac736..0576781 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
@@ -472,19 +472,32 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map,
   Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr;
   Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr;
   Elf64_Addr offset = 0;
+  Elf64_FuncDesc zero_fd = {0, 0, 0};
 
   PPC_DCBT (&plt->fd_aux);
   PPC_DCBT (&plt->fd_func);
-  PPC_DCBT (&rel->fd_aux);
-  PPC_DCBT (&rel->fd_func);
 
-  /* If sym_map is NULL, it's a weak undefined sym;  Leave the plt zero.  */
+  /* If sym_map is NULL, it's a weak undefined sym;  Set the plt to
+     zero.  finaladdr should be zero already in this case, but guard
+     against invalid plt relocations with non-zero addends.  */
   if (sym_map == NULL)
-    return 0;
+    finaladdr = 0;
+
+  /* Don't die here if finaladdr is zero, die if this plt entry is
+     actually called.  Makes a difference when LD_BIND_NOW=1.
+     finaladdr may be zero for a weak undefined symbol, or when an
+     ifunc resolver returns zero.  */
+  if (finaladdr == 0)
+    rel = &zero_fd;
+  else
+    {
+      PPC_DCBT (&rel->fd_aux);
+      PPC_DCBT (&rel->fd_func);
+    }
 
   /* If the opd entry is not yet relocated (because it's from a shared
      object that hasn't been processed yet), then manually reloc it.  */
-  if (map != sym_map && !sym_map->l_relocated
+  if (finaladdr != 0 && map != sym_map && !sym_map->l_relocated
 #if !defined RTLD_BOOTSTRAP && defined SHARED
       /* Bootstrap map doesn't have l_relocated set for it.  */
       && sym_map != &GL(dl_rtld_map)
@@ -522,6 +535,13 @@ elf_machine_plt_conflict (struct link_map *map, lookup_t sym_map,
 #if _CALL_ELF != 2
   Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr;
   Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr;
+  Elf64_FuncDesc zero_fd = {0, 0, 0};
+
+  if (sym_map == NULL)
+    finaladdr = 0;
+
+  if (finaladdr == 0)
+    rel = &zero_fd;
 
   plt->fd_func = rel->fd_func;
   plt->fd_aux = rel->fd_aux;

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                              |    7 +++++++
 sysdeps/powerpc/powerpc64/dl-machine.h |   30 +++++++++++++++++++++++++-----
 2 files changed, 32 insertions(+), 5 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]