diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | elf/Makefile | 4 | ||||
-rw-r--r-- | elf/rtld.c | 27 | ||||
-rw-r--r-- | elf/tst-execstack-prog.c | 35 |
4 files changed, 70 insertions, 5 deletions
@@ -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> * sysdeps/x86_64/dl-machine.h (RTLD_START): Set __libc_stack_end diff --git a/elf/Makefile b/elf/Makefile index 36f205abb2..2e6b6cb2b2 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -159,7 +159,7 @@ test-srcs = tst-pathopt tests-vis-yes = vismain tests-nodelete-yes = nodelete nodelete2 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 modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ 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 LDFLAGS-tst-execstack-needed = -Wl,-z,noexecstack + +LDFLAGS-tst-execstack-prog = -Wl,-z,execstack endif $(objpfx)tst-array1.out: $(objpfx)tst-array1 diff --git a/elf/rtld.c b/elf/rtld.c index c17f621cc9..d57d8838ac 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -648,6 +648,10 @@ dl_main (const ElfW(Phdr) *phdr, GL(dl_rtld_unlock_recursive) = rtld_lock_default_unlock_recursive; #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_envvars (&mode); @@ -748,6 +752,25 @@ of this helper program; chances are you did not intend to run this program.\n\ objects. */ _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) { 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); } - /* 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) /* Initialize the data structures for the search paths for shared objects. */ diff --git a/elf/tst-execstack-prog.c b/elf/tst-execstack-prog.c new file mode 100644 index 0000000000..5a66d63ca9 --- /dev/null +++ b/elf/tst-execstack-prog.c @@ -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" |