Module Name: src
Committed By: riastradh
Date: Mon Aug 26 13:52:56 UTC 2024
Modified Files:
src/sys/kern: kern_entropy.c
src/sys/sys: entropy.h
Log Message:
entropy(9): Factor out subroutines to reset and gather entropy.
`Reset' means we keep the data in the pool, but assume it had zero
entropy. `Gather' means we request samples from all on-demand
sources and wait for the synchronous ones to complete.
No functional change intended, other than to expose new symbols --
just preparation to expose these to acpivmgenid(4), so it can use
these when the VM host notifies us that we, the guest, have been
cloned.
PR kern/58632: getentropy(2) and arc4random(3) do not reseed on VM
fork
To generate a diff of this commit:
cvs rdiff -u -r1.69 -r1.70 src/sys/kern/kern_entropy.c
cvs rdiff -u -r1.5 -r1.6 src/sys/sys/entropy.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/kern_entropy.c
diff -u src/sys/kern/kern_entropy.c:1.69 src/sys/kern/kern_entropy.c:1.70
--- src/sys/kern/kern_entropy.c:1.69 Mon Aug 26 13:48:04 2024
+++ src/sys/kern/kern_entropy.c Mon Aug 26 13:52:56 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_entropy.c,v 1.69 2024/08/26 13:48:04 riastradh Exp $ */
+/* $NetBSD: kern_entropy.c,v 1.70 2024/08/26 13:52:56 riastradh Exp $ */
/*-
* Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_entropy.c,v 1.69 2024/08/26 13:48:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_entropy.c,v 1.70 2024/08/26 13:52:56 riastradh Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -1426,6 +1426,26 @@ sysctl_entropy_consolidate(SYSCTLFN_ARGS
}
/*
+ * entropy_gather()
+ *
+ * Trigger gathering entropy from all on-demand sources, and, if
+ * requested, wait for synchronous sources (but not asynchronous
+ * sources) to complete, or fail with EINTR if interrupted by a
+ * signal.
+ */
+int
+entropy_gather(void)
+{
+ int error;
+
+ mutex_enter(&E->lock);
+ error = entropy_request(ENTROPY_CAPACITY, ENTROPY_WAIT|ENTROPY_SIG);
+ mutex_exit(&E->lock);
+
+ return error;
+}
+
+/*
* sysctl -w kern.entropy.gather=1
*
* Trigger gathering entropy from all on-demand sources, and wait
@@ -1443,12 +1463,8 @@ sysctl_entropy_gather(SYSCTLFN_ARGS)
error = sysctl_lookup(SYSCTLFN_CALL(&node));
if (error || newp == NULL)
return error;
- if (arg) {
- mutex_enter(&E->lock);
- error = entropy_request(ENTROPY_CAPACITY,
- ENTROPY_WAIT|ENTROPY_SIG);
- mutex_exit(&E->lock);
- }
+ if (arg)
+ error = entropy_gather();
return error;
}
@@ -2451,6 +2467,27 @@ entropy_reset_xc(void *arg1 __unused, vo
}
/*
+ * entropy_reset()
+ *
+ * Assume the entropy pool has been exposed, e.g. because the VM
+ * has been cloned. Nix all the pending entropy and set the
+ * needed to maximum.
+ */
+void
+entropy_reset(void)
+{
+
+ xc_broadcast(0, &entropy_reset_xc, NULL, NULL);
+ mutex_enter(&E->lock);
+ E->bitspending = 0;
+ E->samplespending = 0;
+ atomic_store_relaxed(&E->bitsneeded, MINENTROPYBITS);
+ atomic_store_relaxed(&E->samplesneeded, MINSAMPLES);
+ E->consolidate = false;
+ mutex_exit(&E->lock);
+}
+
+/*
* entropy_ioctl(cmd, data)
*
* Handle various /dev/random ioctl queries.
@@ -2728,16 +2765,8 @@ entropy_ioctl(unsigned long cmd, void *d
* If we disabled estimation or collection, nix all the
* pending entropy and set needed to the maximum.
*/
- if (reset) {
- xc_broadcast(0, &entropy_reset_xc, NULL, NULL);
- mutex_enter(&E->lock);
- E->bitspending = 0;
- E->samplespending = 0;
- atomic_store_relaxed(&E->bitsneeded, MINENTROPYBITS);
- atomic_store_relaxed(&E->samplesneeded, MINSAMPLES);
- E->consolidate = false;
- mutex_exit(&E->lock);
- }
+ if (reset)
+ entropy_reset();
/*
* If we changed any of the estimation or collection
@@ -2750,12 +2779,8 @@ entropy_ioctl(unsigned long cmd, void *d
* we have committed side effects, because this ioctl
* command is idempotent, so repeating it is safe.
*/
- if (request) {
- mutex_enter(&E->lock);
- error = entropy_request(ENTROPY_CAPACITY,
- ENTROPY_WAIT|ENTROPY_SIG);
- mutex_exit(&E->lock);
- }
+ if (request)
+ error = entropy_gather();
break;
}
case RNDADDDATA: { /* Enter seed into entropy pool. */
Index: src/sys/sys/entropy.h
diff -u src/sys/sys/entropy.h:1.5 src/sys/sys/entropy.h:1.6
--- src/sys/sys/entropy.h:1.5 Mon Aug 26 13:46:03 2024
+++ src/sys/sys/entropy.h Mon Aug 26 13:52:56 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: entropy.h,v 1.5 2024/08/26 13:46:03 riastradh Exp $ */
+/* $NetBSD: entropy.h,v 1.6 2024/08/26 13:52:56 riastradh Exp $ */
/*-
* Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -49,6 +49,8 @@ struct knote;
#define ENTROPY_HARDFAIL 0x04
void entropy_bootrequest(void);
+void entropy_reset(void);
+int entropy_gather(void);
void entropy_consolidate(void);
int entropy_consolidate_sig(void);
unsigned entropy_epoch(void);