File CVE-2017-5973-qemuu-usb-infinite-loop-while-doing-control-transfer-in-xhci_kick_epctx.patch of Package xen.11298
References: bsc#1025188 CVE-2017-5973
Limits should be big enough that normal guest should not hit it.
Add a tracepoint to log them, just in case. Also, while being
at it, log the existing link trb limit too.
Reported-by: 李强 <address@hidden>
Signed-off-by: Gerd Hoffmann <address@hidden>
---
hw/usb/hcd-xhci.c | 15 ++++++++++++++-
hw/usb/trace-events | 1 +
2 files changed, 15 insertions(+), 1 deletion(-)
Index: xen-4.5.5-testing/tools/qemu-xen-dir-remote/hw/usb/hcd-xhci.c
===================================================================
--- xen-4.5.5-testing.orig/tools/qemu-xen-dir-remote/hw/usb/hcd-xhci.c
+++ xen-4.5.5-testing/tools/qemu-xen-dir-remote/hw/usb/hcd-xhci.c
@@ -53,6 +53,8 @@
#define ER_FULL_HACK
#define TRB_LINK_LIMIT 4
+#define COMMAND_LIMIT 256
+#define TRANSFER_LIMIT 256
#define LEN_CAP 0x40
#define LEN_OPER (0x400 + 0x10 * MAXPORTS)
@@ -1009,6 +1011,7 @@ static TRBType xhci_ring_fetch(XHCIState
return type;
} else {
if (++link_cnt > TRB_LINK_LIMIT) {
+ trace_usb_xhci_enforced_limit("trb-link");
return 0;
}
ring->dequeue = xhci_mask64(trb->parameter);
@@ -2078,6 +2081,7 @@ static void xhci_kick_ep(XHCIState *xhci
XHCIRing *ring;
USBEndpoint *ep = NULL;
uint64_t mfindex;
+ unsigned int count = 0;
int length;
int i;
@@ -2216,6 +2220,10 @@ static void xhci_kick_ep(XHCIState *xhci
epctx->retry = xfer;
break;
}
+ if (count++ > TRANSFER_LIMIT) {
+ trace_usb_xhci_enforced_limit("transfers");
+ break;
+ }
}
ep = xhci_epid_to_usbep(xhci, slotid, epid);
@@ -2683,7 +2691,7 @@ static void xhci_process_commands(XHCISt
TRBType type;
XHCIEvent event = {ER_COMMAND_COMPLETE, CC_SUCCESS};
dma_addr_t addr;
- unsigned int i, slotid = 0;
+ unsigned int i, slotid = 0, count = 0;
DPRINTF("xhci_process_commands()\n");
if (!xhci_running(xhci)) {
@@ -2797,6 +2805,11 @@ static void xhci_process_commands(XHCISt
}
event.slotid = slotid;
xhci_event(xhci, &event, 0);
+
+ if (count++ > COMMAND_LIMIT) {
+ trace_usb_xhci_enforced_limit("commands");
+ return;
+ }
}
}
Index: xen-4.5.5-testing/tools/qemu-xen-dir-remote/trace-events
===================================================================
--- xen-4.5.5-testing.orig/tools/qemu-xen-dir-remote/trace-events
+++ xen-4.5.5-testing/tools/qemu-xen-dir-remote/trace-events
@@ -394,6 +394,7 @@ usb_xhci_xfer_retry(void *xfer) "%p"
usb_xhci_xfer_success(void *xfer, uint32_t bytes) "%p: len %d"
usb_xhci_xfer_error(void *xfer, uint32_t ret) "%p: ret %d"
usb_xhci_unimplemented(const char *item, int nr) "%s (0x%x)"
+usb_xhci_enforced_limit(const char *item) "%s"
# hw/usb/desc.c
usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"