1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-01 10:06:57 +03:00

Fix ifunc support with DT_TEXTREL segments (BZ#20480)

Currently, DT_TEXTREL is incompatible with IFUNC.  When DT_TEXTREL or
DF_TEXTREL is seen, the dynamic linker calls __mprotect on the segments
with PROT_READ|PROT_WRITE before applying dynamic relocations. It leads
to segfault when performing IFUNC resolution (which requires PROT_EXEC
as well for the IFUNC resolver).

This patch makes it call __mprotect with extra PROT_WRITE bit, which
will keep the PROT_EXEC bit if exists, and thus fixes the segfault.
FreeBSD rtld libexec/rtld-elf/rtld.c (reloc_textrel_prot) does the same.

Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu,
sparc64-linux-gnu, sparcv9-linux-gnu, and armv8-linux-gnueabihf.

	Adam J. Richte  <adam_richter2004@yahoo.com>
	Adhemerval Zanella  <adhemerval.zanella@linaro.org>
	Fangrui Song  <maskray@google.com>

	[BZ #20480]
	* config.h.in (CAN_TEXTREL_IFUNC): New define.
	* configure.ac: Add check if linker supports textrel relocation with
	ifunc.
	* elf/dl-reloc.c (_dl_relocate_object): Use all required flags on
	DT_TEXTREL segments, not only PROT_READ and PROT_WRITE.
	* elf/Makefile (ifunc-pie-tests): Add tst-ifunc-textrel.
	(CFLAGS-tst-ifunc-textrel.c): New rule.
	* elf/tst-ifunc-textrel.c: New file.
This commit is contained in:
Adhemerval Zanella
2018-08-27 16:16:43 -03:00
parent d62f9ec0cc
commit b5c45e8375
7 changed files with 155 additions and 12 deletions

47
configure vendored
View File

@ -664,6 +664,7 @@ INSTALL_PROGRAM
sysnames
submachine
multi_arch
libc_cv_textrel_ifunc
no_stack_protector
stack_protector
libc_cv_ssp
@ -4052,6 +4053,52 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_indirect_function" >&5
$as_echo "$libc_cv_gcc_indirect_function" >&6; }
# Check if linker supports textrel relocation with ifunc (used on elf/tests).
# Note that it relies on libc_cv_ld_gnu_indirect_function test above.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker supports textrels along with ifunc" >&5
$as_echo_n "checking whether the linker supports textrels along with ifunc... " >&6; }
if ${libc_cv_textrel_ifunc+:} false; then :
$as_echo_n "(cached) " >&6
else
cat > conftest.S <<EOF
.type foo,%gnu_indirect_function
foo:
.globl _start
_start:
.globl __start
__start:
.data
#ifdef _LP64
.quad foo
#else
.long foo
#endif
.text
.globl address
address:
#ifdef _LP64
.quad address
#else
.long address
#endif
EOF
libc_cv_textrel_ifunc=no
if test $libc_cv_ld_gnu_indirect_function = yes; then
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp -pie -o conftest conftest.S'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; }; then
libc_cv_textrel_ifunc=yes
fi
fi
rm -f conftest*
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_textrel_ifunc" >&5
$as_echo "$libc_cv_textrel_ifunc" >&6; }
# Check if gcc warns about alias for function with incompatible types.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler warns about alias for function with incompatible types" >&5
$as_echo_n "checking if compiler warns about alias for function with incompatible types... " >&6; }