about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-07-12 11:23:43 -0400
committerRich Felker <dalias@aerifal.cx>2012-07-12 11:23:43 -0400
commitbbbe87e35cfeef593e23010e35528e722027567f (patch)
tree6027b9323ad2232739d6ea85c9568a654ca1e506
parentc89f130f39b413d1fb1733166ca63d694685c529 (diff)
downloadmusl-bbbe87e35cfeef593e23010e35528e722027567f.tar.gz
musl-bbbe87e35cfeef593e23010e35528e722027567f.tar.xz
musl-bbbe87e35cfeef593e23010e35528e722027567f.zip
fix several locks that weren't updated right for new futex-based __lock
these could have caused memory corruption due to invalid accesses to
the next field. all should be fixed now; I found the errors with fgrep
-r '__lock(&', which is bogus since the argument should be an array.
-rw-r--r--src/internal/pthread_impl.h6
-rw-r--r--src/thread/pthread_create.c6
-rw-r--r--src/thread/pthread_detach.c4
-rw-r--r--src/thread/pthread_kill.c4
4 files changed, 10 insertions, 10 deletions
diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h
index 0ce3c1e8..46d8fdd2 100644
--- a/src/internal/pthread_impl.h
+++ b/src/internal/pthread_impl.h
@@ -28,13 +28,12 @@ struct pthread {
 	pid_t tid, pid;
 	int tsd_used, errno_val, *errno_ptr;
 	volatile int cancel, canceldisable, cancelasync;
+	int detached;
 	unsigned char *map_base;
 	size_t map_size;
 	void *start_arg;
 	void *(*start)(void *);
 	void *result;
-	int detached;
-	int exitlock;
 	struct __ptcb *cancelbuf;
 	void **tsd;
 	pthread_attr_t attr;
@@ -47,7 +46,8 @@ struct pthread {
 	int unblock_cancel;
 	int delete_timer;
 	locale_t locale;
-	int killlock;
+	int killlock[2];
+	int exitlock[2];
 };
 
 struct __timer {
diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
index ae2f9e4e..94dc308d 100644
--- a/src/thread/pthread_create.c
+++ b/src/thread/pthread_create.c
@@ -24,12 +24,12 @@ void pthread_exit(void *result)
 
 	__pthread_tsd_run_dtors();
 
-	__lock(&self->exitlock);
+	__lock(self->exitlock);
 
 	/* Mark this thread dead before decrementing count */
-	__lock(&self->killlock);
+	__lock(self->killlock);
 	self->dead = 1;
-	a_store(&self->killlock, 0);
+	__unlock(self->killlock);
 
 	do n = libc.threads_minus_1;
 	while (n && a_cas(&libc.threads_minus_1, n, n-1)!=n);
diff --git a/src/thread/pthread_detach.c b/src/thread/pthread_detach.c
index e8032398..651c38eb 100644
--- a/src/thread/pthread_detach.c
+++ b/src/thread/pthread_detach.c
@@ -3,9 +3,9 @@
 int pthread_detach(pthread_t t)
 {
 	/* Cannot detach a thread that's already exiting */
-	if (a_swap(&t->exitlock, 1))
+	if (a_swap(t->exitlock, 1))
 		return pthread_join(t, 0);
 	t->detached = 2;
-	a_store(&t->exitlock, 0);
+	__unlock(t->exitlock);
 	return 0;
 }
diff --git a/src/thread/pthread_kill.c b/src/thread/pthread_kill.c
index 15f70fb9..d9a5096a 100644
--- a/src/thread/pthread_kill.c
+++ b/src/thread/pthread_kill.c
@@ -3,8 +3,8 @@
 int pthread_kill(pthread_t t, int sig)
 {
 	int r;
-	__lock(&t->killlock);
+	__lock(t->killlock);
 	r = t->dead ? ESRCH : -__syscall(SYS_tgkill, t->pid, t->tid, sig);
-	__unlock(&t->killlock);
+	__unlock(t->killlock);
 	return r;
 }