summaryrefslogtreecommitdiff
path: root/sys/dev/usb/usbdi.c
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/usbdi.c
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/usbdi.c')
-rw-r--r--sys/dev/usb/usbdi.c4
1 files changed, 2 insertions, 2 deletions
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);