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