From: Scott Cheloha Subject: Re: pthread_mutex_timedlock(3): don't block forever if the timeout is NULL To: tech@openbsd.org Date: Sat, 27 Jan 2024 18:19:59 -0600 On Tue, Jan 09, 2024 at 11:14:08PM -0600, Scott Cheloha wrote: > 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? Ping. 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 28 Jan 2024 00:19:09 -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 28 Jan 2024 00:19:09 -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