From c4c6e192ac045c06f4aad3afc8e437baf67227b7 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 8 Oct 2013 14:48:05 -0700 Subject: [PATCH] pthread_exit should call __NR_exit with status 0. We shouldn't have been passing the bottom 32 bits of the address used for pthread_join to the kernel. Change-Id: I487e5002d60c27adba51173719213abbee0f183f --- libc/arch-arm/bionic/_exit_with_stack_teardown.S | 2 +- libc/arch-mips/bionic/_exit_with_stack_teardown.S | 4 ++-- libc/arch-x86/bionic/_exit_with_stack_teardown.S | 6 +++--- .../arch-x86_64/bionic/_exit_with_stack_teardown.S | 6 +++--- libc/bionic/bionic_clone.c | 14 +++++--------- libc/bionic/pthread.c | 12 ++++++------ 6 files changed, 20 insertions(+), 24 deletions(-) diff --git a/libc/arch-arm/bionic/_exit_with_stack_teardown.S b/libc/arch-arm/bionic/_exit_with_stack_teardown.S index ac79d4323..1c1354045 100644 --- a/libc/arch-arm/bionic/_exit_with_stack_teardown.S +++ b/libc/arch-arm/bionic/_exit_with_stack_teardown.S @@ -29,7 +29,7 @@ #include #include -// void _exit_with_stack_teardown(void* stackBase, int stackSize, int retCode) +// void _exit_with_stack_teardown(void* stackBase, int stackSize, int status) ENTRY(_exit_with_stack_teardown) mov lr, r2 ldr r7, =__NR_munmap diff --git a/libc/arch-mips/bionic/_exit_with_stack_teardown.S b/libc/arch-mips/bionic/_exit_with_stack_teardown.S index 9974e842b..e89000889 100644 --- a/libc/arch-mips/bionic/_exit_with_stack_teardown.S +++ b/libc/arch-mips/bionic/_exit_with_stack_teardown.S @@ -30,14 +30,14 @@ .text -/* void _exit_with_stack_teardown(void * stackBase, int stackSize, int retCode) */ +// void _exit_with_stack_teardown(void * stackBase, int stackSize, int status) .type _exit_with_stack_teardown, @function .global _exit_with_stack_teardown .align 4 .ent _exit_with_stack_teardown _exit_with_stack_teardown: - move $s0,$a2 /* preserve retCode for exit() call */ + move $s0,$a2 /* preserve status for exit() call */ li $v0,__NR_munmap syscall /* the stack is destroyed by this call */ diff --git a/libc/arch-x86/bionic/_exit_with_stack_teardown.S b/libc/arch-x86/bionic/_exit_with_stack_teardown.S index a036e0d96..d3b554120 100644 --- a/libc/arch-x86/bionic/_exit_with_stack_teardown.S +++ b/libc/arch-x86/bionic/_exit_with_stack_teardown.S @@ -1,12 +1,12 @@ #include #include -// void _exit_with_stack_teardown(void* stackBase, int stackSize, int retCode) +// void _exit_with_stack_teardown(void* stackBase, int stackSize, int status) ENTRY(_exit_with_stack_teardown) // We can trash %ebx here since this call should never return. // We can also take advantage of the fact that the linux syscall trap // handler saves all the registers, so we don't need a stack to keep - // the retCode argument for exit while doing the munmap */ + // the status argument for exit while doing the munmap */ mov 4(%esp), %ebx // stackBase mov 8(%esp), %ecx // stackSize mov $__NR_munmap, %eax @@ -14,7 +14,7 @@ ENTRY(_exit_with_stack_teardown) // If munmap failed, we ignore the failure and exit anyway. - mov %edx, %ebx // retCode + mov %edx, %ebx // status movl $__NR_exit, %eax int $0x80 diff --git a/libc/arch-x86_64/bionic/_exit_with_stack_teardown.S b/libc/arch-x86_64/bionic/_exit_with_stack_teardown.S index a4cd28915..182e0ef3b 100644 --- a/libc/arch-x86_64/bionic/_exit_with_stack_teardown.S +++ b/libc/arch-x86_64/bionic/_exit_with_stack_teardown.S @@ -29,17 +29,17 @@ #include #include -// void _exit_with_stack_teardown(void* stackBase, int stackSize, int retCode) +// void _exit_with_stack_teardown(void* stackBase, int stackSize, int status) ENTRY(_exit_with_stack_teardown) // We take advantage of the fact that the linux syscall trap // handler saves all the registers, so we don't need to save - // the retCode argument for exit(2) while doing the munmap(2). + // the status argument for exit(2) while doing the munmap(2). mov $__NR_munmap, %eax syscall // If munmap failed, ignore the failure and exit anyway. - mov %rdx, %rdi // retCode + mov %rdx, %rdi // status mov $__NR_exit, %eax syscall diff --git a/libc/bionic/bionic_clone.c b/libc/bionic/bionic_clone.c index 84120576e..b603a3a97 100644 --- a/libc/bionic/bionic_clone.c +++ b/libc/bionic/bionic_clone.c @@ -39,21 +39,17 @@ extern int __bionic_clone(unsigned long clone_flags, int (*fn)(void *), void *arg); -extern void _exit_thread(int retCode); +extern void _exit_thread(int status); /* this function is called from the __bionic_clone * assembly fragment to call the thread function * then exit. */ -extern void -__bionic_clone_entry( int (*fn)(void *), void *arg ) -{ - int ret = (*fn)(arg); - _exit_thread(ret); +extern void __bionic_clone_entry(int (*fn)(void*), void* arg) { + int status = (*fn)(arg); + _exit_thread(status); } -int -clone(int (*fn)(void *), void *child_stack, int flags, void* arg, ...) -{ +int clone(int (*fn)(void*), void* child_stack, int flags, void* arg, ...) { va_list args; int *parent_tidptr = NULL; void *new_tls = NULL; diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c index 755b0ac55..ab806c0dc 100644 --- a/libc/bionic/pthread.c +++ b/libc/bionic/pthread.c @@ -44,8 +44,8 @@ extern void pthread_debug_mutex_lock_check(pthread_mutex_t *mutex); extern void pthread_debug_mutex_unlock_check(pthread_mutex_t *mutex); -extern void _exit_with_stack_teardown(void * stackBase, int stackSize, int retCode); -extern void _exit_thread(int retCode); +extern void _exit_with_stack_teardown(void * stackBase, int stackSize, int status); +extern void _exit_thread(int status); int __futex_wake_ex(volatile void *ftx, int pshared, int val) { @@ -143,15 +143,15 @@ void pthread_exit(void * retval) sigfillset(&mask); sigdelset(&mask, SIGSEGV); - (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); + sigprocmask(SIG_SETMASK, &mask, NULL); - // destroy the thread stack if (user_stack) { - _exit_thread((int)retval); + // Cleaning up this thread's stack is the creator's responsibility, not ours. + _exit_thread(0); } else { // We need to munmap the stack we're running on before calling exit. // That's not something we can do in C. - _exit_with_stack_teardown(stack_base, stack_size, (int)retval); + _exit_with_stack_teardown(stack_base, stack_size, 0); } }