diff options
author | 2013-11-07 20:37:33 +0000 | |
---|---|---|
committer | 2013-11-07 20:37:33 +0000 | |
commit | c020f0f683459b6460304c93a8190899bfb76d60 (patch) | |
tree | eba6d131628b0f797e705acec49d1170bff14c51 | |
parent | sync (diff) | |
download | wireguard-openbsd-c020f0f683459b6460304c93a8190899bfb76d60.tar.xz wireguard-openbsd-c020f0f683459b6460304c93a8190899bfb76d60.zip |
In polling mode since r1.101 we could end up dereferencing an
uninitialized variable in case the transfer we were waiting for
timed out; problem reported by oga@bitrig.
So bring uhci_waitintr() in sync with its equivalent in ohci(4)
and ehci(4), stop using an uhci_xfer, do not dereference it and
set the correct status of the transfer.
-rw-r--r-- | sys/dev/usb/uhci.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index 20b587ae435..98352f3da36 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uhci.c,v 1.102 2013/11/07 10:16:27 mpi Exp $ */ +/* $OpenBSD: uhci.c,v 1.103 2013/11/07 20:37:33 mpi Exp $ */ /* $NetBSD: uhci.c,v 1.172 2003/02/23 04:19:26 simonb Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */ @@ -1418,16 +1418,17 @@ uhci_timeout_task(void *addr) void uhci_waitintr(struct uhci_softc *sc, struct usbd_xfer *xfer) { - int timo = xfer->timeout; - struct uhci_xfer *ex; - - DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo)); + int timo; + u_int32_t intrs; xfer->status = USBD_IN_PROGRESS; - for (; timo >= 0; timo--) { + for (timo = xfer->timeout; timo >= 0; timo--) { usb_delay_ms(&sc->sc_bus, 1); - DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS))); - if (UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS) { + if (sc->sc_bus.dying) + break; + intrs = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS; + DPRINTFN(15,("uhci_waitintr: 0x%04x\n", intrs)); + if (intrs) { uhci_intr1(sc); if (xfer->status != USBD_IN_PROGRESS) return; @@ -1436,7 +1437,8 @@ uhci_waitintr(struct uhci_softc *sc, struct usbd_xfer *xfer) /* Timeout */ DPRINTF(("uhci_waitintr: timeout\n")); - uhci_idone(ex); + xfer->status = USBD_TIMEOUT; + usb_transfer_complete(xfer); } void |