diff options
author | Florian Weimer <fweimer@redhat.com> | 2021-05-10 10:31:41 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2021-05-10 10:31:41 +0200 |
commit | 2dd87703d4386f2776c5b5f375a494c91d7f9fe4 (patch) | |
tree | 94c59b0e923242d2ea1fe8992ea574d156fb7ded /nptl | |
parent | ee07b3a7222746fafc5d5cb2163c9609b81615ef (diff) | |
download | glibc-2dd87703d4386f2776c5b5f375a494c91d7f9fe4.tar.gz glibc-2dd87703d4386f2776c5b5f375a494c91d7f9fe4.tar.xz glibc-2dd87703d4386f2776c5b5f375a494c91d7f9fe4.zip |
nptl: Move changing of stack permissions into ld.so
All the stack lists are now in _rtld_global, so it is possible to change stack permissions directly from there, instead of calling into libpthread to do the change. Tested-by: Carlos O'Donell <carlos@redhat.com> Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/allocatestack.c | 63 | ||||
-rw-r--r-- | nptl/nptl-init.c | 4 | ||||
-rw-r--r-- | nptl/pthreadP.h | 7 |
3 files changed, 6 insertions, 68 deletions
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index 46089163f4..12cd1058d4 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -291,31 +291,6 @@ queue_stack (struct pthread *stack) free_stacks (stack_cache_maxsize); } - -static int -change_stack_perm (struct pthread *pd) -{ -#ifdef NEED_SEPARATE_REGISTER_STACK - size_t pagemask = __getpagesize () - 1; - void *stack = (pd->stackblock - + (((((pd->stackblock_size - pd->guardsize) / 2) - & pagemask) + pd->guardsize) & pagemask)); - size_t len = pd->stackblock + pd->stackblock_size - stack; -#elif _STACK_GROWS_DOWN - void *stack = pd->stackblock + pd->guardsize; - size_t len = pd->stackblock_size - pd->guardsize; -#elif _STACK_GROWS_UP - void *stack = pd->stackblock; - size_t len = (uintptr_t) pd - pd->guardsize - (uintptr_t) pd->stackblock; -#else -# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" -#endif - if (__mprotect (stack, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - return errno; - - return 0; -} - /* Return the guard page position on allocated stack. */ static inline char * __attribute ((always_inline)) @@ -625,7 +600,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, if (__builtin_expect ((GL(dl_stack_flags) & PF_X) != 0 && (prot & PROT_EXEC) == 0, 0)) { - int err = change_stack_perm (pd); + int err = __nptl_change_stack_perm (pd); if (err != 0) { /* Free the stack memory we just allocated. */ @@ -780,42 +755,6 @@ __deallocate_stack (struct pthread *pd) lll_unlock (GL (dl_stack_cache_lock), LLL_PRIVATE); } - -int -__make_stacks_executable (void **stack_endp) -{ - /* First the main thread's stack. */ - int err = _dl_make_stack_executable (stack_endp); - if (err != 0) - return err; - - lll_lock (GL (dl_stack_cache_lock), LLL_PRIVATE); - - list_t *runp; - list_for_each (runp, &GL (dl_stack_used)) - { - err = change_stack_perm (list_entry (runp, struct pthread, list)); - if (err != 0) - break; - } - - /* Also change the permission for the currently unused stacks. This - might be wasted time but better spend it here than adding a check - in the fast path. */ - if (err == 0) - list_for_each (runp, &GL (dl_stack_cache)) - { - err = change_stack_perm (list_entry (runp, struct pthread, list)); - if (err != 0) - break; - } - - lll_unlock (GL (dl_stack_cache_lock), LLL_PRIVATE); - - 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/nptl-init.c b/nptl/nptl-init.c index 2fb1117f3e..4c89e7a792 100644 --- a/nptl/nptl-init.c +++ b/nptl/nptl-init.c @@ -173,10 +173,6 @@ __pthread_initialize_minimal_internal (void) __default_pthread_attr.internal.guardsize = GLRO (dl_pagesize); lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE); -#ifdef SHARED - GL(dl_make_stack_executable_hook) = &__make_stacks_executable; -#endif - /* Register the fork generation counter with the libc. */ __libc_pthread_init (__reclaim_stacks); } diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 8ab247f977..3a6b436400 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -335,8 +335,11 @@ extern void __deallocate_stack (struct pthread *pd) attribute_hidden; function also re-initializes the lock for the stack cache. */ extern void __reclaim_stacks (void) attribute_hidden; -/* Make all threads's stacks executable. */ -extern int __make_stacks_executable (void **stack_endp) attribute_hidden; +/* Change the permissions of a thread stack. Called from + _dl_make_stacks_executable and pthread_create. */ +int +__nptl_change_stack_perm (struct pthread *pd); +rtld_hidden_proto (__nptl_change_stack_perm) /* longjmp handling. */ extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe); |