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