[PATCH] [PR libc/18801] PIE binary with STT_GNU_IFUNC symbol and TEXTREL segfaults on x86_64
Paul Pluzhnikov
ppluzhnikov@google.com
Wed Aug 12 06:15:00 GMT 2015
On Tue, Aug 11, 2015 at 10:48 PM, Mike Frysinger <vapier@gentoo.org> wrote:
> i don't see why we should make any change. it isn't ld's problem that the
> restrictive runtime prevents things. ld already issues a warning when you
> have textrels in shared segments, so let's leave it at that.
For the test case, ld does not issue any warnings:
gcc -fPIE -pie tst-pie-ifunc-txtrel.S
readelf -d a.out | grep TEXTREL
0x0000000000000016 (TEXTREL) 0x0
Apparently --warn-shared-textrel is not the default for GNU ld (GNU
Binutils for Ubuntu) 2.24.
The resulting binary crashes inside ld.so, for no apparent reason:
(gdb) r
Starting program: /tmp/a.out
Program received signal SIGSEGV, Segmentation fault.
0x000055555555478b in selector ()
(gdb) bt
#0 0x000055555555478b in selector ()
#1 0x00007ffff7de680f in elf_machine_rela (reloc=0x555555554510,
reloc=0x555555554510, skip_ifunc=<optimized out>,
reloc_addr_arg=0x555555554798 <main+2>, version=<optimized out>,
sym=<optimized out>, map=0x7ffff7ffe1c8) at
../sysdeps/x86_64/dl-machine.h:467
#2 elf_dynamic_do_Rela (skip_ifunc=<optimized out>, lazy=<optimized
out>, nrelative=<optimized out>, relsize=<optimized out>,
reladdr=<optimized out>, map=0x7ffff7ffe1c8) at do-rel.h:149
#3 _dl_relocate_object (scope=<optimized out>, reloc_mode=<optimized
out>, consider_profiling=<optimized out>, consider_profiling@entry=0)
at dl-reloc.c:264
#4 0x00007ffff7dddafa in dl_main (phdr=<optimized out>,
phdr@entry=0x555555554040, phnum=<optimized out>, phnum@entry=9,
user_entry=user_entry@entry=0x7fffffffe2b8, auxv=<optimized out>) at
rtld.c:2204
#5 0x00007ffff7df1565 in _dl_sysdep_start
(start_argptr=start_argptr@entry=0x7fffffffe3a0,
dl_main=dl_main@entry=0x7ffff7ddb910 <dl_main>) at
../elf/dl-sysdep.c:249
#6 0x00007ffff7ddecf8 in _dl_start_final (arg=0x7fffffffe3a0) at rtld.c:332
#7 _dl_start (arg=0x7fffffffe3a0) at rtld.c:558
#8 0x00007ffff7ddb2d8 in _start () at rtld.c:875
There is nothing obviously wrong with the executable (aside from the
fact that it has TEXTREL). ld.so took away execute permissions from
selector(), when arguably it shouldn't have.
The patch fixes that, but the fix will cause additional damage (not
currently present) to other TEXTREL binaries under SELinux and other
security systems.
I think it would be nice to have behavior other than what's currently
happening. Either ld.so should support TEXTREL binaries with IFUNCs,
or it should refuse to run them.
I guess it could also try to make W+E page, and IF that fails, issue a
warning and change to current behavior. That way, a TEXTREL+IFUNC
binary will run correctly outside SELinux, will warn, then crash under
SELinux. A TEXTREL without IFUNC will also run correctly outside
SELinux, and will warn but still work under SELinux (i.e. almost same
as current behavior).
> ftr, the issue you describe is not specific to selinux as other security
> systems have been doing this for a long time. e.g. grsec/PaX.
Yes, I am aware of these. I am just using SELinux as a synonym for
"SELinux and other security systems".
--
Paul Pluzhnikov
More information about the Libc-alpha
mailing list