Module Name: src
Committed By: riastradh
Date: Wed Mar 16 23:56:33 UTC 2022
Modified Files:
src/share/man/man9: cprng.9
src/sys/kern: subr_cprng.c
Log Message:
cprng(9): Forbid use in hard interrupt context.
May need access to the global entropy pool (infrequently). This way
the global entropy pool lock can be lowered to IPL_SOFTSERIAL too,
with a little additional work.
To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/share/man/man9/cprng.9
cvs rdiff -u -r1.41 -r1.42 src/sys/kern/subr_cprng.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/share/man/man9/cprng.9
diff -u src/share/man/man9/cprng.9:1.14 src/share/man/man9/cprng.9:1.15
--- src/share/man/man9/cprng.9:1.14 Mon Aug 17 06:07:53 2020
+++ src/share/man/man9/cprng.9 Wed Mar 16 23:56:33 2022
@@ -1,4 +1,4 @@
-.\" $NetBSD: cprng.9,v 1.14 2020/08/17 06:07:53 wiz Exp $
+.\" $NetBSD: cprng.9,v 1.15 2022/03/16 23:56:33 riastradh Exp $
.\"
.\" Copyright (c) 2011-2015 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -93,16 +93,14 @@ the strong generator can also be created
.Pp
The
.Nm
-functions may be used at interrupt priority level
-.Dv IPL_VM
-or below,
+functions may be used in soft interrupt context,
except for
.Fn cprng_strong_create
and
.Fn cprng_strong_destroy
which are allowed only at
-.Dv IPL_NONE ;
-see
+.Dv IPL_NONE
+in thread context; see
.Xr spl 9 .
.Pp
The
Index: src/sys/kern/subr_cprng.c
diff -u src/sys/kern/subr_cprng.c:1.41 src/sys/kern/subr_cprng.c:1.42
--- src/sys/kern/subr_cprng.c:1.41 Wed Jul 21 06:35:45 2021
+++ src/sys/kern/subr_cprng.c Wed Mar 16 23:56:33 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_cprng.c,v 1.41 2021/07/21 06:35:45 skrll Exp $ */
+/* $NetBSD: subr_cprng.c,v 1.42 2022/03/16 23:56:33 riastradh Exp $ */
/*-
* Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -44,7 +44,7 @@
* This code serves the first two categories without having extra
* logic for /dev/random.
*
- * kern_cprng - available at IPL_VM or lower
+ * kern_cprng - available at IPL_SOFTSERIAL or lower
* user_cprng - available only at IPL_NONE in thread context
*
* The name kern_cprng is for hysterical raisins. The name
@@ -52,7 +52,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.41 2021/07/21 06:35:45 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.42 2022/03/16 23:56:33 riastradh Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -88,7 +88,6 @@ struct cprng_cpu {
struct nist_hash_drbg *cc_drbg;
struct {
struct evcnt reseed;
- struct evcnt intr;
} *cc_evcnt;
unsigned cc_epoch;
};
@@ -99,7 +98,7 @@ static void cprng_init_cpu(void *, void
static void cprng_fini_cpu(void *, void *, struct cpu_info *);
/* Well-known CPRNG instances */
-struct cprng_strong *kern_cprng __read_mostly; /* IPL_VM */
+struct cprng_strong *kern_cprng __read_mostly; /* IPL_SOFTSERIAL */
struct cprng_strong *user_cprng __read_mostly; /* IPL_NONE */
static struct sysctllog *cprng_sysctllog __read_mostly;
@@ -112,12 +111,12 @@ cprng_init(void)
panic("NIST Hash_DRBG failed self-test");
/*
- * Create CPRNG instances at two IPLs: IPL_VM for kernel use
- * that may occur inside IPL_VM interrupt handlers (!!??!?!?),
+ * Create CPRNG instances at two IPLs: IPL_SOFTSERIAL for
+ * kernel use that may occur inside soft interrupt handlers,
* and IPL_NONE for userland use which need not block
* interrupts.
*/
- kern_cprng = cprng_strong_create("kern", IPL_VM, 0);
+ kern_cprng = cprng_strong_create("kern", IPL_SOFTSERIAL, 0);
user_cprng = cprng_strong_create("user", IPL_NONE, 0);
/* Create kern.urandom and kern.arandom sysctl nodes. */
@@ -246,8 +245,6 @@ cprng_init_cpu(void *ptr, void *cookie,
/* Attach the event counters. */
/* XXX ci_cpuname may not be initialized early enough. */
cpuname = ci->ci_cpuname[0] == '\0' ? "cpu0" : ci->ci_cpuname;
- evcnt_attach_dynamic(&cc->cc_evcnt->intr, EVCNT_TYPE_MISC, NULL,
- cpuname, "cprng_strong intr");
evcnt_attach_dynamic(&cc->cc_evcnt->reseed, EVCNT_TYPE_MISC, NULL,
cpuname, "cprng_strong reseed");
@@ -261,7 +258,6 @@ cprng_fini_cpu(void *ptr, void *cookie,
struct cprng_cpu *cc = ptr;
evcnt_detach(&cc->cc_evcnt->reseed);
- evcnt_detach(&cc->cc_evcnt->intr);
if (__predict_false(nist_hash_drbg_destroy(cc->cc_drbg)))
panic("nist_hash_drbg_destroy");
@@ -277,6 +273,9 @@ cprng_strong(struct cprng_strong *cprng,
unsigned epoch;
int s;
+ /* Not allowed in hard interrupt context. */
+ KASSERT(!cpu_intr_p());
+
/*
* Verify maximum request length. Caller should really limit
* their requests to 32 bytes to avoid spending much time with
@@ -292,9 +291,6 @@ cprng_strong(struct cprng_strong *cprng,
cc = percpu_getref(cprng->cs_percpu);
s = splraiseipl(cprng->cs_iplcookie);
- if (cpu_intr_p())
- cc->cc_evcnt->intr.ev_count++;
-
/* If the entropy epoch has changed, (re)seed. */
epoch = entropy_epoch();
if (__predict_false(epoch != cc->cc_epoch)) {