* elf/rtld.c (dl_main): In rtld_is_main case, reinitialize

GL(dl_stack_flags) according to rtld's own PT_GNU_STACK.
	Move GL(dl_make_stack_executable_hook) initialization up.
	* elf/tst-execstack-prog.c: New file.
	* elf/Makefile (tests-execstack-yes): Add it.
	(LDFLAGS-tst-execstack-prog): New variable.
This commit is contained in:
Roland McGrath 2003-09-24 01:56:08 +00:00
parent 217ed70e13
commit c70ba48888
4 changed files with 70 additions and 5 deletions

View File

@ -1,3 +1,12 @@
2003-09-23 Roland McGrath <roland@redhat.com>
* elf/rtld.c (dl_main): In rtld_is_main case, reinitialize
GL(dl_stack_flags) according to rtld's own PT_GNU_STACK.
Move GL(dl_make_stack_executable_hook) initialization up.
* elf/tst-execstack-prog.c: New file.
* elf/Makefile (tests-execstack-yes): Add it.
(LDFLAGS-tst-execstack-prog): New variable.
2003-09-23 Jakub Jelinek <jakub@redhat.com> 2003-09-23 Jakub Jelinek <jakub@redhat.com>
* sysdeps/x86_64/dl-machine.h (RTLD_START): Set __libc_stack_end * sysdeps/x86_64/dl-machine.h (RTLD_START): Set __libc_stack_end

View File

@ -159,7 +159,7 @@ test-srcs = tst-pathopt
tests-vis-yes = vismain tests-vis-yes = vismain
tests-nodelete-yes = nodelete nodelete2 tests-nodelete-yes = nodelete nodelete2
tests-nodlopen-yes = nodlopen nodlopen2 tests-nodlopen-yes = nodlopen nodlopen2
tests-execstack-yes = tst-execstack tst-execstack-needed tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog
endif endif
modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
testobj1_1 failobj constload2 constload3 unloadmod \ testobj1_1 failobj constload2 constload3 unloadmod \
@ -673,6 +673,8 @@ LDFLAGS-tst-execstack-mod = -Wl,-z,execstack
$(objpfx)tst-execstack-needed: $(objpfx)tst-execstack-mod.so $(objpfx)tst-execstack-needed: $(objpfx)tst-execstack-mod.so
LDFLAGS-tst-execstack-needed = -Wl,-z,noexecstack LDFLAGS-tst-execstack-needed = -Wl,-z,noexecstack
LDFLAGS-tst-execstack-prog = -Wl,-z,execstack
endif endif
$(objpfx)tst-array1.out: $(objpfx)tst-array1 $(objpfx)tst-array1.out: $(objpfx)tst-array1

View File

@ -648,6 +648,10 @@ dl_main (const ElfW(Phdr) *phdr,
GL(dl_rtld_unlock_recursive) = rtld_lock_default_unlock_recursive; GL(dl_rtld_unlock_recursive) = rtld_lock_default_unlock_recursive;
#endif #endif
/* The explicit initialization here is cheaper than processing the reloc
in the _rtld_local definition's initializer. */
GL(dl_make_stack_executable_hook) = &_dl_make_stack_executable;
/* Process the environment variable which control the behaviour. */ /* Process the environment variable which control the behaviour. */
process_envvars (&mode); process_envvars (&mode);
@ -748,6 +752,25 @@ of this helper program; chances are you did not intend to run this program.\n\
objects. */ objects. */
_dl_init_paths (library_path); _dl_init_paths (library_path);
/* The initialization of _dl_stack_flags done below assumes the
executable's PT_GNU_STACK may have been honored by the kernel, and
so a PT_GNU_STACK with PF_X set means the stack started out with
execute permission. However, this is not really true if the
dynamic linker is the executable the kernel loaded. For this
case, we must reinitialize _dl_stack_flags to match the dynamic
linker itself. If the dynamic linker was built with a
PT_GNU_STACK, then the kernel may have loaded us with a
nonexecutable stack that we will have to make executable when we
load the program below unless it has a PT_GNU_STACK indicating
nonexecutable stack is ok. */
for (ph = phdr; ph < &phdr[phnum]; ++ph)
if (ph->p_type == PT_GNU_STACK)
{
GL(dl_stack_flags) = ph->p_flags;
break;
}
if (__builtin_expect (mode, normal) == verify) if (__builtin_expect (mode, normal) == verify)
{ {
const char *objname; const char *objname;
@ -954,10 +977,6 @@ of this helper program; chances are you did not intend to run this program.\n\
_exit (has_interp ? 0 : 2); _exit (has_interp ? 0 : 2);
} }
/* The explicit initialization here is cheaper than processing the reloc
in the _rtld_local definition's initializer. */
GL(dl_make_stack_executable_hook) = &_dl_make_stack_executable;
if (! rtld_is_main) if (! rtld_is_main)
/* Initialize the data structures for the search paths for shared /* Initialize the data structures for the search paths for shared
objects. */ objects. */

35
elf/tst-execstack-prog.c Normal file
View File

@ -0,0 +1,35 @@
/* Test program for executable stacks in an executable itself. */
#include <dlfcn.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <error.h>
#include "tst-execstack-mod.c" /* This defines the `tryme' test function. */
static void deeper (void (*f) (void));
static int
do_test (void)
{
tryme ();
/* Test that growing the stack region gets new executable pages too. */
deeper (&tryme);
return 0;
}
static void
deeper (void (*f) (void))
{
char stack[1100 * 1024];
memfrob (stack, sizeof stack);
(*f) ();
memfrob (stack, sizeof stack);
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"