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

Reply via email to