diff options
author | 2020-01-04 11:40:56 +0000 | |
---|---|---|
committer | 2020-01-04 11:40:56 +0000 | |
commit | ea9883cc1d60bfac84af96526b0c3b2a89cf3cac (patch) | |
tree | 90ded78abb249352e5a9adbe3ae7b4b67edd0d04 | |
parent | Convert sleep to tsleep_nsec(9) and use unique sleeping identifiers. (diff) | |
download | wireguard-openbsd-ea9883cc1d60bfac84af96526b0c3b2a89cf3cac.tar.xz wireguard-openbsd-ea9883cc1d60bfac84af96526b0c3b2a89cf3cac.zip |
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@
-rw-r--r-- | sys/dev/usb/uhidev.c | 28 |
1 files 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; |