git: 8b3f74c15296 - stable/15 - libthr: Fix LIBPTHREAD_QUEUE_FIFO range

From: ShengYi Hung <aokblast_at_FreeBSD.org>
Date: Sun, 01 Nov 2026 22:08:43 UTC
The branch stable/15 has been updated by aokblast:

URL: https://cgit.FreeBSD.org/src/commit/?id=8b3f74c152968ec7b8b57a96bbe3b2091b2b817a

commit 8b3f74c152968ec7b8b57a96bbe3b2091b2b817a
Author:     ShengYi Hung <aokblast@FreeBSD.org>
AuthorDate: 2026-10-08 18:53:06 +0000
Commit:     ShengYi Hung <aokblast@FreeBSD.org>
CommitDate: 2026-11-01 22:08:26 +0000

    libthr: Fix LIBPTHREAD_QUEUE_FIFO range
    
    LIBPTHREAD_QUEUE_FIFO is used in bitwise offset, we set the limit to
    0~31 so that it won't cause undefined behavior. Also, create a new
    helper function to do getenv++strtol directly and check the boundary of
    the valid value.
    
    Reviewed by:    kib
    MFC after:      2 weeks
    Differential Revision: https://reviews.freebsd.org/D60487
    
    (cherry picked from commit 5fb07bbcd5d5d9a865d9e7765fb93e9ba5edef1c)
---
 lib/libthr/libthr.3          |  4 ++--
 lib/libthr/thread/thr_init.c | 33 ++++++++++++++++++++++++---------
 2 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/lib/libthr/libthr.3 b/lib/libthr/libthr.3
index 4b1995a79414..afd2556c274e 100644
--- a/lib/libthr/libthr.3
+++ b/lib/libthr/libthr.3
@@ -27,7 +27,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd October 1, 2021
+.Dd October 8, 2026
 .Dt LIBTHR 3
 .Os
 .Sh NAME
@@ -199,7 +199,7 @@ The value is the count of loop operations.
 The integer value of the variable specifies how often blocked
 threads are inserted at the head of the sleep queue, instead of its tail.
 Bigger values reduce the frequency of the FIFO discipline.
-The value must be between 0 and 255.
+The value must be between 0 and 31.
 .It Dv LIBPTHREAD_UMTX_MIN_TIMEOUT
 The minimal amount of time, in nanoseconds, the thread is required to sleep
 for pthread operations specifying a timeout.
diff --git a/lib/libthr/thread/thr_init.c b/lib/libthr/thread/thr_init.c
index 162ef7dfe7a9..fca09affa53e 100644
--- a/lib/libthr/thread/thr_init.c
+++ b/lib/libthr/thread/thr_init.c
@@ -475,6 +475,24 @@ __thr_get_main_stack_lim(size_t *lim)
 	return (false);
 }
 
+static bool
+getenv_int(const char *name, int mn, int mx, int *result)
+{
+	const char *env;
+	char *endptr;
+	long val;
+
+	env = getenv(name);
+	if (env == NULL || *env == '\0')
+		return (false);
+	val = strtol(env, &endptr, 10);
+	if (*endptr != '\0' || errno != 0 || val < mn || val > mx) {
+		return (false);
+	}
+	*result = val;
+	return (true);
+}
+
 static void
 init_private(void)
 {
@@ -519,15 +537,12 @@ init_private(void)
 		_thr_guard_default = _thr_page_size;
 		_pthread_attr_default.guardsize_attr = _thr_guard_default;
 		_pthread_attr_default.stacksize_attr = _thr_stack_default;
-		env = getenv("LIBPTHREAD_SPINLOOPS");
-		if (env)
-			_thr_spinloops = atoi(env);
-		env = getenv("LIBPTHREAD_YIELDLOOPS");
-		if (env)
-			_thr_yieldloops = atoi(env);
-		env = getenv("LIBPTHREAD_QUEUE_FIFO");
-		if (env)
-			_thr_queuefifo = atoi(env);
+		(void)getenv_int("LIBPTHREAD_SPINLOOPS", 0, INT_MAX,
+		    &_thr_spinloops);
+		(void)getenv_int("LIBPTHREAD_YIELDLOOPS", 0, INT_MAX,
+		    &_thr_yieldloops);
+		(void)getenv_int("LIBPTHREAD_QUEUE_FIFO", 0, 31,
+		    &_thr_queuefifo);
 		env = getenv("LIBPTHREAD_UMTX_MIN_TIMEOUT");
 		if (env) {
 			char *endptr;