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 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
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 \
$(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
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);
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;
_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. */
--- /dev/null
+/* 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"