Close pipes before freeing transfer descriptors on close(2), otherwise a use-after-free is possible in usbd_abort_pipe(9).
Ok? Index: uhidev.c =================================================================== RCS file: /cvs/src/sys/dev/usb/uhidev.c,v retrieving revision 1.77 diff -u -p -r1.77 uhidev.c --- uhidev.c 13 Nov 2019 10:40:03 -0000 1.77 +++ uhidev.c 20 Dec 2019 13:11:14 -0000 @@ -606,6 +606,19 @@ uhidev_close(struct uhidev *scd) return; DPRINTF(("uhidev_close: close pipe\n")); + /* Disable interrupts. */ + if (sc->sc_opipe != NULL) { + usbd_abort_pipe(sc->sc_opipe); + usbd_close_pipe(sc->sc_opipe); + sc->sc_opipe = NULL; + } + + if (sc->sc_ipipe != NULL) { + usbd_abort_pipe(sc->sc_ipipe); + usbd_close_pipe(sc->sc_ipipe); + sc->sc_ipipe = NULL; + } + if (sc->sc_oxfer != NULL) { usbd_free_xfer(sc->sc_oxfer); sc->sc_oxfer = NULL; @@ -619,19 +632,6 @@ uhidev_close(struct uhidev *scd) if (sc->sc_ixfer != NULL) { usbd_free_xfer(sc->sc_ixfer); sc->sc_ixfer = NULL; - } - - /* Disable interrupts. */ - if (sc->sc_opipe != NULL) { - usbd_abort_pipe(sc->sc_opipe); - usbd_close_pipe(sc->sc_opipe); - sc->sc_opipe = NULL; - } - - if (sc->sc_ipipe != NULL) { - usbd_abort_pipe(sc->sc_ipipe); - usbd_close_pipe(sc->sc_ipipe); - sc->sc_ipipe = NULL; } if (sc->sc_ibuf != NULL) {