From c4c6e192ac045c06f4aad3afc8e437baf67227b7 Mon Sep 17 00:00:00 2001
From: Elliott Hughes <enh@google.com>
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 <machine/asm.h>
 #include <asm/unistd.h>
 
-// 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 <asm/unistd.h>
 #include <machine/asm.h>
 
-// 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 <asm/unistd.h>
 #include <machine/asm.h>
 
-// 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);
     }
 }