diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2017-03-17 09:26:00 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2017-03-17 09:26:00 +0000 |
commit | 3ae287c8642208202871c2e845ac394d6ce1282e (patch) | |
tree | ce7e3e04f1171263687ff0b627833df0acd812fd | |
parent | 424885b336b415bbcdcba666903c4fd9df672370 (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.c | 19 |
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 |