Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/usb ualea(4): Enter the data under the softc lock.



details:   https://anonhg.NetBSD.org/src/rev/7ef56e58e545
branches:  trunk
changeset: 364388:7ef56e58e545
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Mar 20 13:18:30 2022 +0000

description:
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).

diffstat:

 sys/dev/usb/ualea.c |  18 +++++++++++-------
 1 files changed, 11 insertions(+), 7 deletions(-)

diffs (42 lines):

diff -r 35bff6bcb761 -r 7ef56e58e545 sys/dev/usb/ualea.c
--- a/sys/dev/usb/ualea.c       Sun Mar 20 13:18:11 2022 +0000
+++ b/sys/dev/usb/ualea.c       Sun Mar 20 13:18:30 2022 +0000
@@ -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 @@
            "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);



Home | Main Index | Thread Index | Old Index