svn commit: r362644 - head/usr.sbin/bhyve

Peter Grehan grehan at FreeBSD.org
Fri Jun 26 08:20:39 UTC 2020


Author: grehan
Date: Fri Jun 26 08:20:38 2020
New Revision: 362644
URL: https://svnweb.freebsd.org/changeset/base/362644

Log:
  Prevent calling USB backends multiple times.
  
  The TRB processing loop could potentially call a back-end twice
  with the same status transaction. While this was generally benign,
  some code paths in the tablet backend weren't set up to handle
  this case, resulting in a NULL dereference.
  
  Fix by
   - returning a STALL error when an invalid request was seen in the backend
   - skipping a call to the backend if the number of packets in a status
     transaction was zero (this code fragment was taken from the Intel ACRN
     xhci backend)
  
  PR:	246964
  Reported by:  Ali Abdallah
  Discussed with: Leon Dang (author)
  Reviewed by: jhb (#bhyve), Leon Dang
  Approved by: jhb
  Obtained from:  Intel ACRN (partially)
  MFC after: 2 weeks
  Differential Revision:	https://reviews.freebsd.org/D25228

Modified:
  head/usr.sbin/bhyve/pci_xhci.c
  head/usr.sbin/bhyve/usb_mouse.c

Modified: head/usr.sbin/bhyve/pci_xhci.c
==============================================================================
--- head/usr.sbin/bhyve/pci_xhci.c	Fri Jun 26 06:11:50 2020	(r362643)
+++ head/usr.sbin/bhyve/pci_xhci.c	Fri Jun 26 08:20:38 2020	(r362644)
@@ -1843,6 +1843,9 @@ retry:
 
 	DPRINTF(("pci_xhci[%d]: xfer->ndata %u", __LINE__, xfer->ndata));
 
+	if (xfer->ndata <= 0)
+		goto errout;
+
 	if (epid == 1) {
 		err = USB_ERR_NOT_STARTED;
 		if (dev->dev_ue->ue_request != NULL)
@@ -1857,6 +1860,7 @@ retry:
 
 	err = USB_TO_XHCI_ERR(err);
 	if ((err == XHCI_TRB_ERROR_SUCCESS) ||
+	    (err == XHCI_TRB_ERROR_STALL) ||
 	    (err == XHCI_TRB_ERROR_SHORT_PKT)) {
 		err = pci_xhci_xfer_complete(sc, xfer, slot, epid, &do_intr);
 		if (err != XHCI_TRB_ERROR_SUCCESS)

Modified: head/usr.sbin/bhyve/usb_mouse.c
==============================================================================
--- head/usr.sbin/bhyve/usb_mouse.c	Fri Jun 26 06:11:50 2020	(r362643)
+++ head/usr.sbin/bhyve/usb_mouse.c	Fri Jun 26 08:20:38 2020	(r362644)
@@ -390,7 +390,7 @@ umouse_request(void *scarg, struct usb_data_xfer *xfer
 			         "sizeof(umouse_dev_desc) %lu",
 			         len, sizeof(umouse_dev_desc)));
 			if ((value & 0xFF) != 0) {
-				err = USB_ERR_IOERROR;
+				err = USB_ERR_STALLED;
 				goto done;
 			}
 			if (len > sizeof(umouse_dev_desc)) {
@@ -405,7 +405,7 @@ umouse_request(void *scarg, struct usb_data_xfer *xfer
 		case UDESC_CONFIG:
 			DPRINTF(("umouse: (->UDESC_CONFIG)"));
 			if ((value & 0xFF) != 0) {
-				err = USB_ERR_IOERROR;
+				err = USB_ERR_STALLED;
 				goto done;
 			}
 			if (len > sizeof(umouse_confd)) {
@@ -474,7 +474,7 @@ umouse_request(void *scarg, struct usb_data_xfer *xfer
 
 		default:
 			DPRINTF(("umouse: unknown(%d)->ERROR", value >> 8));
-			err = USB_ERR_IOERROR;
+			err = USB_ERR_STALLED;
 			goto done;
 		}
 		eshort = data->blen > 0;
@@ -498,7 +498,7 @@ umouse_request(void *scarg, struct usb_data_xfer *xfer
 			break;
 		default:
 			DPRINTF(("umouse: IO ERROR"));
-			err = USB_ERR_IOERROR;
+			err = USB_ERR_STALLED;
 			goto done;
 		}
 		eshort = data->blen > 0;
@@ -509,7 +509,7 @@ umouse_request(void *scarg, struct usb_data_xfer *xfer
 		if (index != 0) {
 			DPRINTF(("umouse get_interface, invalid index %d",
 			        index));
-			err = USB_ERR_IOERROR;
+			err = USB_ERR_STALLED;
 			goto done;
 		}
 
@@ -580,7 +580,7 @@ umouse_request(void *scarg, struct usb_data_xfer *xfer
 	case UREQ(UR_SET_FEATURE, UT_WRITE_INTERFACE):
 	case UREQ(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
 		DPRINTF(("umouse: (UR_CLEAR_FEATURE, UT_WRITE_INTERFACE)"));
-		err = USB_ERR_IOERROR;
+		err = USB_ERR_STALLED;
 		goto done;
 
 	case UREQ(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
@@ -619,7 +619,7 @@ umouse_request(void *scarg, struct usb_data_xfer *xfer
 			memcpy(data->buf, &sc->um_report, len);
 			data->bdone += len;
 		} else {
-			err = USB_ERR_IOERROR;
+			err = USB_ERR_STALLED;
 			goto done;
 		}
 		eshort = data->blen > 0;
@@ -661,7 +661,7 @@ umouse_request(void *scarg, struct usb_data_xfer *xfer
 
 	default:
 		DPRINTF(("**** umouse request unhandled"));
-		err = USB_ERR_IOERROR;
+		err = USB_ERR_STALLED;
 		break;
 	}
 


More information about the svn-src-head mailing list