From ea9883cc1d60bfac84af96526b0c3b2a89cf3cac Mon Sep 17 00:00:00 2001 From: mpi Date: Sat, 4 Jan 2020 11:40:56 +0000 Subject: [PATCH] Prevent use-after-free in uhidev_close(). Close pipes before freeing transfers, otherwise accessing elements in pipe->queue, like in usbd_abort_pipe(), will result in a crash. Problem reported by reyk@, ok visa@ --- sys/dev/usb/uhidev.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c index 8f55b056507..c4cac47ba37 100644 --- a/sys/dev/usb/uhidev.c +++ b/sys/dev/usb/uhidev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uhidev.c,v 1.77 2019/11/13 10:40:03 patrick Exp $ */ +/* $OpenBSD: uhidev.c,v 1.78 2020/01/04 11:40:56 mpi Exp $ */ /* $NetBSD: uhidev.c,v 1.14 2003/03/11 16:44:00 augustss Exp $ */ /* @@ -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; @@ -621,19 +634,6 @@ uhidev_close(struct uhidev *scd) 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) { free(sc->sc_ibuf, M_USBDEV, sc->sc_isize); sc->sc_ibuf = NULL;