diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2017-03-10 11:18:49 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2017-03-10 11:18:49 +0000 |
commit | 863f5e679091d5af40787f5863a9f61b84db11c5 (patch) | |
tree | 8ea6fddec874b5e4d597584e64da3e8c688710ae /sys/dev/usb | |
parent | 8be19390d68917bbad04b8329790eb50f5281208 (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.c | 4 | ||||
-rw-r--r-- | sys/dev/usb/ehci.c | 4 | ||||
-rw-r--r-- | sys/dev/usb/ohci.c | 4 | ||||
-rw-r--r-- | sys/dev/usb/uhci.c | 4 | ||||
-rw-r--r-- | sys/dev/usb/usbdi.c | 4 | ||||
-rw-r--r-- | sys/dev/usb/xhci.c | 4 |
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); } |