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);

Reply via email to