PR 18801 * elf/dl-reloc.c (_dl_relocate_object): Preserve the original permissions when protecting the segment for writing it. * sysdeps/x86_64/Makefile (ifunc-pie-txtrel-test): New test. * sysdeps/x86_64/tst-pie-ifunc-txtrel.S: New file. diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 61252d7..1c0ed7c 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -201,13 +201,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], newp->start = PTR_ALIGN_DOWN (ph->p_vaddr, GLRO(dl_pagesize)) + (caddr_t) l->l_addr; - if (__mprotect (newp->start, newp->len, PROT_READ|PROT_WRITE) < 0) - { - errstring = N_("cannot make segment writable for relocation"); - call_error: - _dl_signal_error (errno, l->l_name, NULL, errstring); - } - #if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7 newp->prot = (PF_TO_PROT >> ((ph->p_flags & (PF_R | PF_W | PF_X)) * 4)) & 0xf; @@ -220,6 +213,13 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], if (ph->p_flags & PF_X) newp->prot |= PROT_EXEC; #endif + if (__mprotect (newp->start, newp->len, newp->prot | PROT_WRITE) < 0) + { + errstring = N_("cannot make segment writable for relocation"); + call_error: + _dl_signal_error (errno, l->l_name, NULL, errstring); + } + newp->next = textrels; textrels = newp; } diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile index ef70a50..c0a9c43 100644 --- a/sysdeps/x86_64/Makefile +++ b/sysdeps/x86_64/Makefile @@ -34,6 +34,10 @@ tests-pie += $(quad-pie-test) $(objpfx)tst-quad1pie: $(objpfx)tst-quadmod1pie.o $(objpfx)tst-quad2pie: $(objpfx)tst-quadmod2pie.o +ifunc-pie-txtrel-test += tst-pie-ifunc-txtrel +tests += $(ifunc-pie-txtrel-test) +tests-pie += $(ifunc-pie-txtrel-test) + tests += tst-audit3 tst-audit4 tst-audit5 tst-audit10 ifeq (yes,$(config-cflags-avx)) tests += tst-audit6 tst-audit7 diff --git a/sysdeps/x86_64/tst-pie-ifunc-txtrel.S b/sysdeps/x86_64/tst-pie-ifunc-txtrel.S index e69de29..77360c4 100644 --- a/sysdeps/x86_64/tst-pie-ifunc-txtrel.S +++ b/sysdeps/x86_64/tst-pie-ifunc-txtrel.S @@ -0,0 +1,32 @@ +/* Verify that a PIE binary with TEXTREL and a IFUNC symbol executes. + + Copyright (C) 2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +foo: + movl $0, %eax + ret +selector: + movabsq $foo, %rax + ret + .type selector, %gnu_indirect_function + .globl main +main: + movabsq $selector, %rax + call *%rax + ret + .section .note.GNU-stack,"",@progbits