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