Module Name:    src
Committed By:   riastradh
Date:           Thu Mar  6 00:54:27 UTC 2025

Modified Files:
        src/lib/libc/gen: arc4random.c
        src/tests/lib/libc/gen: t_arc4random.c

Log Message:
t_arc4random: Test arc4random_global.per_thread, not .initialized.

If arc4random_initialize has been called, and thr_keycreate failed,
then .initialized will be true but .per_thread will be false -- and
.thread_key will be garbage (some other thread key for another
purpose, most likely).  This path was enabled by allowing
thr_keycreate to fail instead of aborting the process.

This hasn't caused trouble yet, mainly because we don't do anything
to inject faults into thr_keycreate in these tests.  Tweak the
global_threadkeylimit test while here to provoke a crash with the
wrong conditional.

Fix a similar edge case in the little test program embedded in
arc4random.c (which should maybe just go away now that we have atf
tests).

PR lib/59117: arc4random has some failure modes it shouldn't


To generate a diff of this commit:
cvs rdiff -u -r1.44 -r1.45 src/lib/libc/gen/arc4random.c
cvs rdiff -u -r1.3 -r1.4 src/tests/lib/libc/gen/t_arc4random.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/gen/arc4random.c
diff -u src/lib/libc/gen/arc4random.c:1.44 src/lib/libc/gen/arc4random.c:1.45
--- src/lib/libc/gen/arc4random.c:1.44	Thu Mar  6 00:53:26 2025
+++ src/lib/libc/gen/arc4random.c	Thu Mar  6 00:54:27 2025
@@ -1,4 +1,4 @@
-/*	$NetBSD: arc4random.c,v 1.44 2025/03/06 00:53:26 riastradh Exp $	*/
+/*	$NetBSD: arc4random.c,v 1.45 2025/03/06 00:54:27 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -52,7 +52,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: arc4random.c,v 1.44 2025/03/06 00:53:26 riastradh Exp $");
+__RCSID("$NetBSD: arc4random.c,v 1.45 2025/03/06 00:54:27 riastradh Exp $");
 
 #include "namespace.h"
 #include "reentrant.h"
@@ -810,7 +810,9 @@ main(int argc __unused, char **argv __un
 		 */
 		struct arc4random_prng *prng = NULL;
 #ifdef _REENTRANT
-		prng = thr_getspecific(arc4random_global.thread_key);
+		prng = arc4random_global.per_thread
+		    ? thr_getspecific(arc4random_global.thread_key)
+		    : NULL;
 #endif
 		if (prng == NULL)
 			prng = &arc4random_global.prng;

Index: src/tests/lib/libc/gen/t_arc4random.c
diff -u src/tests/lib/libc/gen/t_arc4random.c:1.3 src/tests/lib/libc/gen/t_arc4random.c:1.4
--- src/tests/lib/libc/gen/t_arc4random.c:1.3	Wed Mar  5 21:30:34 2025
+++ src/tests/lib/libc/gen/t_arc4random.c	Thu Mar  6 00:54:27 2025
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_arc4random.c,v 1.3 2025/03/05 21:30:34 riastradh Exp $	*/
+/*	$NetBSD: t_arc4random.c,v 1.4 2025/03/06 00:54:27 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2024 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
 #define	_REENTRANT
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_arc4random.c,v 1.3 2025/03/05 21:30:34 riastradh Exp $");
+__RCSID("$NetBSD: t_arc4random.c,v 1.4 2025/03/06 00:54:27 riastradh Exp $");
 
 #include <sys/resource.h>
 #include <sys/stat.h>
@@ -83,7 +83,7 @@ arc4random_prng(void)
 	 * (i.e., libc was built with _REENTRANT), get the thread-local
 	 * arc4random state if there is one.
 	 */
-	if (arc4random_global.initialized)
+	if (arc4random_global.per_thread)
 		prng = thr_getspecific(arc4random_global.thread_key);
 
 	/*
@@ -545,11 +545,15 @@ ATF_TC_BODY(global_threadkeylimit, tc)
 	ATF_CHECK(!iszero(buf, sizeof(buf)));	/* Pr[fail] = 1/2^256 */
 
 	/*
-	 * Artificially disable the per-thread state and clear the
-	 * epoch.
+	 * Artificially disable the per-thread state, make it an
+	 * invalid thread key altogether, and clear the epoch.  Make
+	 * sure we're using the global PRNG state now.
 	 */
 	arc4random_global.per_thread = false;
+	memset(&arc4random_global.thread_key, 0x5a,
+	    sizeof(arc4random_global.thread_key));
 	arc4random_global.prng.arc4_epoch = 0;
+	ATF_CHECK(arc4random_prng() == &arc4random_global.prng);
 
 	/*
 	 * Get a sample again and make sure it wasn't repeated, which

Reply via email to