From 54ee14b3882bc7f2fcace383ee12da765e86e2ee Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 24 Sep 2003 03:22:56 +0000 Subject: Update. 2003-09-23 Ulrich Drepper * sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions [libc] (GLIBC_2.3.3): Add setcontext, getcontext, swapcontext, and makecontext. * sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h: Correct change for include Altivec support for PPC32. It was not compatible. * sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h: Adjust offsets for ucontext_t change. * sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S: Adjust for ucontext_t change. Add compatibility code. * sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S: Likewise. Patch by Paul Mackerras . 2003-02-25 Randolph Chung * sysdeps/hppa/Makefile: Include compat code in build. * sysdeps/hppa/libgcc-compat.c: New file. * sysdeps/hppa/Dist: Add libgcc-compat.c. * sysdeps/hppa/Versions [GLIBC_2.2]: Add __clz_tab. --- nptl/ChangeLog | 18 ++++++++++++++++++ nptl/Makefile | 7 +++++++ nptl/allocatestack.c | 53 +++++++++++++++++++++++++++++++++++++++++++++------- nptl/init.c | 2 ++ nptl/pthreadP.h | 3 +++ 5 files changed, 76 insertions(+), 7 deletions(-) (limited to 'nptl') diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 00bfbf9ad8..031c9e08cd 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,21 @@ +2003-09-23 Jakub Jelinek + + * Makefile (tests): Only add tst-execstack if have-z-execstack is yes. + +2003-09-23 Roland McGrath + + * tst-execstack.c: New file. + * Makefile (tests): Add it. + ($(objpfx)tst-execstack, $(objpfx)tst-execstack.out): New targets. + (LDFLAGS-tst-execstack): New variable. + + * allocatestack.c (allocate_stack): Use GL(dl_stack_flags) to decide + whether to use PROT_EXEC for stack mmap. + (__make_stacks_executable): New function. + * pthreadP.h: Declare it. + * init.c (__pthread_initialize_minimal_internal): Set + GL(dl_make_stack_executable_hook) to that. + 2003-09-22 Ulrich Drepper * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Adjust for latest diff --git a/nptl/Makefile b/nptl/Makefile index d592137caf..cf438bbdb6 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -253,6 +253,9 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \ endif ifeq ($(build-shared),yes) tests += tst-atfork2 tst-tls3 tst-tls4 tst-tls5 tst-_res1 +ifeq ($(have-z-execstack),yes) +tests += tst-execstack +endif endif modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \ @@ -540,3 +543,7 @@ endif endif tst-exec4-ARGS = $(built-program-cmd) + +$(objpfx)tst-execstack: $(libdl) +$(objpfx)tst-execstack.out: $(elf-objpfx)tst-execstack-mod.so +LDFLAGS-tst-execstack = -Wl,-z,noexecstack diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index 6ada1fe138..dc501650b8 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -351,11 +351,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, } else { - /* Allocate some anonymous memory. If possible use the - cache. */ + /* Allocate some anonymous memory. If possible use the cache. */ size_t guardsize; size_t reqsize; void *mem; + const int prot = (PROT_READ | PROT_WRITE + | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0)); #if COLORING_INCREMENT != 0 /* Add one more page for stack coloring. Don't do it for stacks @@ -392,7 +393,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, size += pagesize_m1 + 1; #endif - mem = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, + mem = mmap (NULL, size, prot, MAP_PRIVATE | MAP_ANONYMOUS | ARCH_MAP_FLAGS, -1, 0); if (__builtin_expect (mem == MAP_FAILED, 0)) @@ -546,17 +547,16 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, char *oldguard = mem + (((size - pd->guardsize) / 2) & ~pagesize_m1); if (oldguard < guard - && mprotect (oldguard, guard - oldguard, - PROT_READ | PROT_WRITE | PROT_EXEC) != 0) + && mprotect (oldguard, guard - oldguard, prot) != 0) goto mprot_error; if (mprotect (guard + guardsize, oldguard + pd->guardsize - guard - guardsize, - PROT_READ | PROT_WRITE | PROT_EXEC) != 0) + prot) != 0) goto mprot_error; #else if (mprotect ((char *) mem + guardsize, pd->guardsize - guardsize, - PROT_READ | PROT_WRITE | PROT_EXEC) != 0) + prot) != 0) goto mprot_error; #endif @@ -616,6 +616,45 @@ __deallocate_stack (struct pthread *pd) } +int +internal_function +__make_stacks_executable (void) +{ +#ifdef NEED_SEPARATE_REGISTER_STACK + const size_t pagemask = ~(__getpagesize () - 1); +#endif + + lll_lock (stack_cache_lock); + + int err = 0; + list_t *runp; + list_for_each (runp, &stack_used) + { + struct pthread *const pd = list_entry (runp, struct pthread, list); +#ifdef NEED_SEPARATE_REGISTER_STACK + void *stack = (pd->stackblock + + (((((pd->stackblock_size - pd->guardsize) / 2) + & pagemask) + pd->guardsize) & pagemask)); + size_t len = pd->stackblock + pd->stackblock_size - stack; +#else + void *stack = pd->stackblock + pd->guardsize; + size_t len = pd->stackblock_size - pd->guardsize; +#endif + if (mprotect (stack, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) + { + err = errno; + break; + } + } + + lll_unlock (stack_cache_lock); + + _dl_make_stack_executable (); + + return err; +} + + /* In case of a fork() call the memory allocation in the child will be the same but only one thread is running. All stacks except that of the one running thread are not used anymore. We have to recycle diff --git a/nptl/init.c b/nptl/init.c index 7b8b2b0c54..36b65425f5 100644 --- a/nptl/init.c +++ b/nptl/init.c @@ -283,6 +283,8 @@ __pthread_initialize_minimal_internal (void) GL(dl_load_lock).mutex.__data.__count = 0; while (rtld_lock_count-- > 0) INTUSE (__pthread_mutex_lock) (&GL(dl_load_lock).mutex); + + GL(dl_make_stack_executable_hook) = &__make_stacks_executable; #endif GL(dl_init_static_tls) = &__pthread_init_static_tls; diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 4159ea6862..986e3788fb 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -215,6 +215,9 @@ extern void __deallocate_stack (struct pthread *pd) function also re-initializes the lock for the stack cache. */ extern void __reclaim_stacks (void) attribute_hidden; +/* Make all threads's stacks executable. */ +int __make_stacks_executable (void) internal_function attribute_hidden; + /* longjmp handling. */ extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe); #if defined NOT_IN_libc && defined IS_IN_libpthread -- cgit v1.2.3