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