summaryrefslogtreecommitdiff
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2017-03-10 11:18:49 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2017-03-10 11:18:49 +0000
commit863f5e679091d5af40787f5863a9f61b84db11c5 (patch)
tree8ea6fddec874b5e4d597584e64da3e8c688710ae /sys/dev/usb
parent8be19390d68917bbad04b8329790eb50f5281208 (diff)
Fix a use-after-free when sending root hub control transfers.
*_root_ctrl_start() routines are synchronous and all end up calling usb_transfer_complete() in the non-error case. After calling this function it is unsafe to dereference ``xfer'' since the transfer callback has been called. So returning USBD_IN_PROGRESS is wrong in this case since transfers are always completed at this point. So return USBD_NORMAL_COMPLETION or the corresponding error code if something wrong happen.
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/dwc2/dwc2.c4
-rw-r--r--sys/dev/usb/ehci.c4
-rw-r--r--sys/dev/usb/ohci.c4
-rw-r--r--sys/dev/usb/uhci.c4
-rw-r--r--sys/dev/usb/usbdi.c4
-rw-r--r--sys/dev/usb/xhci.c4
6 files changed, 12 insertions, 12 deletions
diff --git a/sys/dev/usb/dwc2/dwc2.c b/sys/dev/usb/dwc2/dwc2.c
index c24dff757f7..7fb32dcb4ca 100644
--- a/sys/dev/usb/dwc2/dwc2.c
+++ b/sys/dev/usb/dwc2/dwc2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dwc2.c,v 1.42 2017/03/10 09:14:06 mpi Exp $ */
+/* $OpenBSD: dwc2.c,v 1.43 2017/03/10 11:18:48 mpi Exp $ */
/* $NetBSD: dwc2.c,v 1.32 2014/09/02 23:26:20 macallan Exp $ */
/*-
@@ -841,7 +841,7 @@ fail:
usb_transfer_complete(xfer);
splx(s);
- return USBD_IN_PROGRESS;
+ return err;
}
STATIC void
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
index 1a6e0bbeee2..8f9f6d28832 100644
--- a/sys/dev/usb/ehci.c
+++ b/sys/dev/usb/ehci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ehci.c,v 1.196 2017/03/10 09:14:06 mpi Exp $ */
+/* $OpenBSD: ehci.c,v 1.197 2017/03/10 11:18:48 mpi Exp $ */
/* $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $ */
/*
@@ -2138,7 +2138,7 @@ ehci_root_ctrl_start(struct usbd_xfer *xfer)
s = splusb();
usb_transfer_complete(xfer);
splx(s);
- return (USBD_IN_PROGRESS);
+ return (err);
}
void
diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c
index ee9370970a4..72e5abef11d 100644
--- a/sys/dev/usb/ohci.c
+++ b/sys/dev/usb/ohci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ohci.c,v 1.148 2017/03/10 09:14:06 mpi Exp $ */
+/* $OpenBSD: ohci.c,v 1.149 2017/03/10 11:18:48 mpi Exp $ */
/* $NetBSD: ohci.c,v 1.139 2003/02/22 05:24:16 tsutsui Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
@@ -2550,7 +2550,7 @@ ohci_root_ctrl_start(struct usbd_xfer *xfer)
s = splusb();
usb_transfer_complete(xfer);
splx(s);
- return (USBD_IN_PROGRESS);
+ return (err);
}
/* Abort a root control request. */
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c
index 4cff58d21d8..7cc3127a7e3 100644
--- a/sys/dev/usb/uhci.c
+++ b/sys/dev/usb/uhci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhci.c,v 1.141 2017/03/10 09:14:06 mpi Exp $ */
+/* $OpenBSD: uhci.c,v 1.142 2017/03/10 11:18:48 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 $ */
@@ -3184,7 +3184,7 @@ uhci_root_ctrl_start(struct usbd_xfer *xfer)
s = splusb();
usb_transfer_complete(xfer);
splx(s);
- return (USBD_IN_PROGRESS);
+ return (err);
}
/* Abort a root control request. */
diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c
index 6f3c6dd1c72..3b9ac674412 100644
--- a/sys/dev/usb/usbdi.c
+++ b/sys/dev/usb/usbdi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: usbdi.c,v 1.88 2017/03/10 09:14:06 mpi Exp $ */
+/* $OpenBSD: usbdi.c,v 1.89 2017/03/10 11:18:48 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 $ */
@@ -322,7 +322,7 @@ usbd_transfer(struct usbd_xfer *xfer)
err = pipe->methods->transfer(xfer);
- if (err != USBD_IN_PROGRESS && err) {
+ if (err != USBD_IN_PROGRESS && err != USBD_NORMAL_COMPLETION) {
/* The transfer has not been queued, so free buffer. */
if (xfer->rqflags & URQ_AUTO_DMABUF) {
usb_freemem(bus, &xfer->dmabuf);
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c
index f78424c2475..c2c23137106 100644
--- a/sys/dev/usb/xhci.c
+++ b/sys/dev/usb/xhci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xhci.c,v 1.71 2017/03/10 09:14:06 mpi Exp $ */
+/* $OpenBSD: xhci.c,v 1.72 2017/03/10 11:18:48 mpi Exp $ */
/*
* Copyright (c) 2014-2015 Martin Pieuchot
@@ -2345,7 +2345,7 @@ ret:
s = splusb();
usb_transfer_complete(xfer);
splx(s);
- return (USBD_IN_PROGRESS);
+ return (err);
}