diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2020-01-04 11:40:57 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2020-01-04 11:40:57 +0000 |
commit | f0b4938f5667c6462d2b99f3e9cd8a5e85b5e8c6 (patch) | |
tree | 7975c4b69f64b33ae22860af728a27192f5299d4 /sys/dev/usb/uhidev.c | |
parent | b570324fa2261a50d102e10842d64434f9630dc4 (diff) |
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@
Diffstat (limited to 'sys/dev/usb/uhidev.c')
-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; |