Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/usb Fix error handling, to prevent kernel crashes wh...



details:   https://anonhg.NetBSD.org/src/rev/6a9ddb2cc30b
branches:  trunk
changeset: 459507:6a9ddb2cc30b
user:      maxv <maxv%NetBSD.org@localhost>
date:      Sat Sep 14 12:38:40 2019 +0000

description:
Fix error handling, to prevent kernel crashes when detaching an umcs0
device.

Found with vHCI.

diffstat:

 sys/dev/usb/umcs.c |  15 +++++++++++++--
 1 files changed, 13 insertions(+), 2 deletions(-)

diffs (57 lines):

diff -r 2838a7b92dd9 -r 6a9ddb2cc30b sys/dev/usb/umcs.c
--- a/sys/dev/usb/umcs.c        Sat Sep 14 12:37:34 2019 +0000
+++ b/sys/dev/usb/umcs.c        Sat Sep 14 12:38:40 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: umcs.c,v 1.13 2019/05/09 02:43:35 mrg Exp $ */
+/* $NetBSD: umcs.c,v 1.14 2019/09/14 12:38:40 maxv Exp $ */
 /* $FreeBSD: head/sys/dev/usb/serial/umcs.c 260559 2014-01-12 11:44:28Z hselasky $ */
 
 /*-
@@ -41,7 +41,7 @@
  *
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umcs.c,v 1.13 2019/05/09 02:43:35 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umcs.c,v 1.14 2019/09/14 12:38:40 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -85,6 +85,10 @@
 
 struct umcs7840_softc {
        device_t sc_dev;                /* ourself */
+       enum {
+               UMCS_INIT_NONE,
+               UMCS_INIT_INITED
+       } sc_init_state;
        struct usbd_interface *sc_iface; /* the usb interface */
        struct usbd_device *sc_udev;    /* the usb device */
        struct usbd_pipe *sc_intr_pipe; /* interrupt pipe */
@@ -193,6 +197,7 @@
        sc->sc_dev = self;
        sc->sc_udev = uaa->uaa_device;
        sc->sc_dying = false;
+       sc->sc_init_state = UMCS_INIT_NONE;
 
        if (usbd_set_config_index(sc->sc_udev, MCS7840_CONFIG_INDEX, 1) != 0) {
                aprint_error(": could not set configuration no\n");
@@ -288,6 +293,8 @@
 
        usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
 
+       sc->sc_init_state = UMCS_INIT_INITED;
+
        memset(&ucaa, 0, sizeof(ucaa));
        ucaa.ucaa_ibufsize = 256;
        ucaa.ucaa_obufsize = 256;
@@ -517,6 +524,10 @@
                kmem_free(sc->sc_intr_buf, sc->sc_intr_buflen);
                sc->sc_intr_buf = NULL;
        }
+
+       if (sc->sc_init_state < UMCS_INIT_INITED)
+               return 0;
+
        usb_rem_task_wait(sc->sc_udev, &sc->sc_change_task, USB_TASKQ_DRIVER,
            NULL);
 



Home | Main Index | Thread Index | Old Index