about summary refs log tree commit diff
path: root/sysdeps/i386
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-03-26 12:30:45 +1030
committerAlan Modra <amodra@gmail.com>2015-03-26 12:30:45 +1030
commit19a6a3acd10e04fc3aba8941b44918acc7003aa2 (patch)
tree5ead95a6797f89518cb7f6ef6ff7764c14fd7cc4 /sysdeps/i386
parentefd5b641dd793fe385e1685047f2c82f4811076c (diff)
downloadglibc-19a6a3acd10e04fc3aba8941b44918acc7003aa2.tar.gz
glibc-19a6a3acd10e04fc3aba8941b44918acc7003aa2.tar.xz
glibc-19a6a3acd10e04fc3aba8941b44918acc7003aa2.zip
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.
Diffstat (limited to 'sysdeps/i386')
0 files changed, 0 insertions, 0 deletions