summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2017-03-17 09:26:00 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2017-03-17 09:26:00 +0000
commit3ae287c8642208202871c2e845ac394d6ce1282e (patch)
treece7e3e04f1171263687ff0b627833df0acd812fd
parent424885b336b415bbcdcba666903c4fd9df672370 (diff)
ubcmtp(4) works because of a use-after-free. Many more drivers are
certainly doing the same. So revert r1.85 for the moment, we're too close from the release and these bugs have been there for years. Regression reported by tb@ on bugs@
-rw-r--r--sys/dev/usb/usbdi.c19
1 files changed, 6 insertions, 13 deletions
diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c
index 3b9ac674412..80866e48f2a 100644
--- a/sys/dev/usb/usbdi.c
+++ b/sys/dev/usb/usbdi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: usbdi.c,v 1.89 2017/03/10 11:18:48 mpi Exp $ */
+/* $OpenBSD: usbdi.c,v 1.90 2017/03/17 09:25:59 mpi Exp $ */
/* $NetBSD: usbdi.c,v 1.103 2002/09/27 15:37:38 provos Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */
@@ -716,7 +716,6 @@ usb_transfer_complete(struct usbd_xfer *xfer)
{
struct usbd_pipe *pipe = xfer->pipe;
int polling = pipe->device->bus->use_polling;
- int status, flags;
SPLUSBCHECK;
@@ -792,13 +791,6 @@ usb_transfer_complete(struct usbd_xfer *xfer)
xfer->status = USBD_SHORT_XFER;
}
- /*
- * We cannot dereference ``xfer'' after calling the callback as
- * it might free it.
- */
- status = xfer->status;
- flags = xfer->flags;
-
if (pipe->repeat) {
if (xfer->callback)
xfer->callback(xfer, xfer->priv, xfer->status);
@@ -815,16 +807,17 @@ usb_transfer_complete(struct usbd_xfer *xfer)
* a new transfer as it will more likely results in the same
* error.
*/
- if (status == USBD_IOERROR)
+ if (xfer->status == USBD_IOERROR)
pipe->repeat = 0;
- if ((flags & USBD_SYNCHRONOUS) && !polling)
+ if ((xfer->flags & USBD_SYNCHRONOUS) && !polling)
wakeup(xfer);
if (!pipe->repeat) {
/* XXX should we stop the queue on all errors? */
- if ((status == USBD_CANCELLED || status == USBD_IOERROR ||
- status == USBD_TIMEOUT) &&
+ if ((xfer->status == USBD_CANCELLED ||
+ xfer->status == USBD_IOERROR ||
+ xfer->status == USBD_TIMEOUT) &&
pipe->iface != NULL) /* not control pipe */
pipe->running = 0;
else