Download raw body.
pthread_mutex_timedlock(3): don't block forever if the timeout is NULL
Both pthread_mutex_timedlock(3) implementations pass the timeout
parameter from the caller through to the internal implementation
function. In both of those functions, a NULL timeout pointer means
"no timeout" or "block indefinitely".
So, we have accidentally extended the pthread_mutex_timedlock(3)
specification with special, undocumented behavior when the timeout
pointer is NULL.
The easy fix is to copy the timeout to the stack before passing it on.
This change will cause any code that depends upon the current behavior
to segfault instead of blocking indefinitely. I think it's unlikely
such code exists. It it does exist, it is not portable.
ok?
Index: rthread_mutex.c
===================================================================
RCS file: /cvs/src/lib/libc/thread/rthread_mutex.c,v
diff -u -p -r1.5 rthread_mutex.c
--- rthread_mutex.c 13 Feb 2019 13:09:32 -0000 1.5
+++ rthread_mutex.c 10 Jan 2024 04:44:57 -0000
@@ -211,9 +211,11 @@ pthread_mutex_trylock(pthread_mutex_t *m
}
int
-pthread_mutex_timedlock(pthread_mutex_t *mutexp, const struct timespec *abs)
+pthread_mutex_timedlock(pthread_mutex_t *mutexp, const struct timespec *absp)
{
- return (_rthread_mutex_timedlock(mutexp, 0, abs, 1));
+ struct timespec abs = *absp;
+
+ return (_rthread_mutex_timedlock(mutexp, 0, &abs, 1));
}
int
Index: rthread_sync.c
===================================================================
RCS file: /cvs/src/lib/libc/thread/rthread_sync.c,v
diff -u -p -r1.6 rthread_sync.c
--- rthread_sync.c 10 Jan 2024 04:28:43 -0000 1.6
+++ rthread_sync.c 10 Jan 2024 04:44:57 -0000
@@ -179,9 +179,11 @@ pthread_mutex_trylock(pthread_mutex_t *p
}
int
-pthread_mutex_timedlock(pthread_mutex_t *p, const struct timespec *abstime)
+pthread_mutex_timedlock(pthread_mutex_t *p, const struct timespec *abstimep)
{
- return (_rthread_mutex_lock(p, 0, abstime));
+ struct timespec abstime = *abstimep;
+
+ return (_rthread_mutex_lock(p, 0, &abstime));
}
int
pthread_mutex_timedlock(3): don't block forever if the timeout is NULL