Module Name: src
Committed By: riastradh
Date: Sun Mar 20 13:18:30 UTC 2022
Modified Files:
src/sys/dev/usb: ualea.c
Log Message:
ualea(4): Enter the data under the softc lock.
This avoids a race with a concurrent ualea_get updating sc_needed,
which could lead to hang when requesting more entropy.
ualea(4) now survives
sysctl -w kern.entropy.depletion=1
cat </dev/random >/dev/null &
cat </dev/random >/dev/null &
without hanging for longer (even if yanked and reinserted in the
middle, although the detach path is not relevant to the bug this
change fixes).
To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/sys/dev/usb/ualea.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/usb/ualea.c
diff -u src/sys/dev/usb/ualea.c:1.18 src/sys/dev/usb/ualea.c:1.19
--- src/sys/dev/usb/ualea.c:1.18 Sun Mar 20 13:13:10 2022
+++ src/sys/dev/usb/ualea.c Sun Mar 20 13:18:30 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: ualea.c,v 1.18 2022/03/20 13:13:10 riastradh Exp $ */
+/* $NetBSD: ualea.c,v 1.19 2022/03/20 13:18:30 riastradh Exp $ */
/*-
* Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ualea.c,v 1.18 2022/03/20 13:13:10 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ualea.c,v 1.19 2022/03/20 13:18:30 riastradh Exp $");
#include <sys/types.h>
#include <sys/atomic.h>
@@ -250,14 +250,18 @@ ualea_xfer_done(struct usbd_xfer *xfer,
"pktsize %"PRIu32" > %"PRIu16" (max)",
pktsize, sc->sc_maxpktsize);
- /* Add the data to the pool. */
- rnd_add_data(&sc->sc_rnd, pkt, pktsize, NBBY*pktsize);
-
/*
- * Debit what we contributed from what we need, mark the xfer
- * as done, and reschedule the xfer if we still need more.
+ * Enter the data, debit what we contributed from what we need,
+ * mark the xfer as done, and reschedule the xfer if we still
+ * need more.
+ *
+ * Must enter the data under the lock so it happens atomically
+ * with updating sc_needed -- otherwise we might hang needing
+ * entropy and not scheduling xfer. Must not touch pkt after
+ * clearing sc_inflight and possibly rescheduling the xfer.
*/
mutex_enter(&sc->sc_lock);
+ rnd_add_data(&sc->sc_rnd, pkt, pktsize, NBBY*pktsize);
sc->sc_needed -= MIN(sc->sc_needed, pktsize);
sc->sc_inflight = false;
ualea_xfer(sc);