Module Name: src Committed By: mrg Date: Wed May 1 06:01:01 UTC 2019
Modified Files: src/sys/dev/usb: ucom.c Log Message: fix a locking botch in ucomhwiflow(): tty.c always calls t_hwiflow() with tty_lock held, and the caller of this for ucom always holds sc->sc_lock when calling down into the tty layer. don't try to re-take the sc_lock in ucomhwiflow() (locking against myself is triggered here currently), but instead assert that the lock is already held _and_ that tty_lock is held. in ucom_detach(), when closing pipes set sc_bulkin_pipe and sc_bulkout_pipe to NULL. fixes bug noticed by code inspection: a failed detach would attempt to close them a second time. To generate a diff of this commit: cvs rdiff -u -r1.122 -r1.123 src/sys/dev/usb/ucom.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/ucom.c diff -u src/sys/dev/usb/ucom.c:1.122 src/sys/dev/usb/ucom.c:1.123 --- src/sys/dev/usb/ucom.c:1.122 Sat Apr 20 05:53:18 2019 +++ src/sys/dev/usb/ucom.c Wed May 1 06:01:01 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: ucom.c,v 1.122 2019/04/20 05:53:18 mrg Exp $ */ +/* $NetBSD: ucom.c,v 1.123 2019/05/01 06:01:01 mrg Exp $ */ /* * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.122 2019/04/20 05:53:18 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.123 2019/05/01 06:01:01 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -413,10 +413,14 @@ ucom_detach(device_t self, int flags) pmf_device_deregister(self); - if (sc->sc_bulkin_pipe != NULL) + if (sc->sc_bulkin_pipe != NULL) { usbd_abort_pipe(sc->sc_bulkin_pipe); - if (sc->sc_bulkout_pipe != NULL) + sc->sc_bulkin_pipe = NULL; + } + if (sc->sc_bulkout_pipe != NULL) { usbd_abort_pipe(sc->sc_bulkout_pipe); + sc->sc_bulkout_pipe = NULL; + } mutex_enter(&sc->sc_lock); @@ -1263,7 +1267,9 @@ ucomhwiflow(struct tty *tp, int block) if (sc == NULL) return 0; - mutex_enter(&sc->sc_lock); + KASSERT(&sc->sc_lock); + KASSERT(mutex_owned(&tty_lock)); + old = sc->sc_rx_stopped; sc->sc_rx_stopped = (u_char)block; @@ -1273,7 +1279,6 @@ ucomhwiflow(struct tty *tp, int block) softint_schedule(sc->sc_si); kpreempt_enable(); } - mutex_exit(&sc->sc_lock); return 1; }