summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2019-09-25 21:49:53 -0400
committerRich Felker <dalias@aerifal.cx>2019-09-25 21:49:53 -0400
commit29bad49d72e5aeedb97d2bb2af44838d934026a0 (patch)
tree320a06fd7a4318149b3b0dd779b6e299868fe7a1 /src
parent7d5c5706a0e1d2f4019a92e1a869d71d552bbb49 (diff)
downloadmusl-29bad49d72e5aeedb97d2bb2af44838d934026a0.tar.gz
fix data race in timer_create with SIGEV_THREAD notification
in the timer thread start function, self->timer_id was accessed without synchronization; the timer thread could fail to see the store from the calling thread, resulting in timer_delete failing to delete the correct kernel-level timer. this fix is based on a patch by changdiankang, but with the load moved to after receiving the timer_delete signal rather than just after the start barrier, so as not to retain the possibility of data race with timer_delete.
Diffstat (limited to 'src')
-rw-r--r--src/time/timer_create.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/src/time/timer_create.c b/src/time/timer_create.c
index c5e40a19..455d49fc 100644
--- a/src/time/timer_create.c
+++ b/src/time/timer_create.c
@@ -1,5 +1,6 @@
#include <time.h>
#include <setjmp.h>
+#include <limits.h>
#include "pthread_impl.h"
struct ksigevent {
@@ -48,7 +49,6 @@ static void *start(void *arg)
{
pthread_t self = __pthread_self();
struct start_args *args = arg;
- int id = self->timer_id;
jmp_buf jb;
void (*notify)(union sigval) = args->sev->sigev_notify_function;
@@ -65,7 +65,7 @@ static void *start(void *arg)
}
if (self->timer_id < 0) break;
}
- __syscall(SYS_timer_delete, id);
+ __syscall(SYS_timer_delete, self->timer_id & INT_MAX);
return 0;
}