diff options
Diffstat (limited to 'app-emulation/qemu/files/qemu-2.8.0-CVE-2017-5973.patch')
-rw-r--r-- | app-emulation/qemu/files/qemu-2.8.0-CVE-2017-5973.patch | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/app-emulation/qemu/files/qemu-2.8.0-CVE-2017-5973.patch b/app-emulation/qemu/files/qemu-2.8.0-CVE-2017-5973.patch new file mode 100644 index 000000000000..50ff3c997924 --- /dev/null +++ b/app-emulation/qemu/files/qemu-2.8.0-CVE-2017-5973.patch @@ -0,0 +1,87 @@ +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(-) + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index fbf8a8b..28dd2f2 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -51,6 +51,8 @@ + #define EV_QUEUE (((3 * 24) + 16) * MAXSLOTS) + + #define TRB_LINK_LIMIT 4 ++#define COMMAND_LIMIT 256 ++#define TRANSFER_LIMIT 256 + + #define LEN_CAP 0x40 + #define LEN_OPER (0x400 + 0x10 * MAXPORTS) +@@ -943,6 +945,7 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb, + return type; + } else { + if (++link_cnt > TRB_LINK_LIMIT) { ++ trace_usb_xhci_enforced_limit("trb-link"); + return 0; + } + ring->dequeue = xhci_mask64(trb->parameter); +@@ -2060,6 +2063,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid) + XHCIRing *ring; + USBEndpoint *ep = NULL; + uint64_t mfindex; ++ unsigned int count = 0; + int length; + int i; + +@@ -2172,6 +2176,10 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid) + epctx->retry = xfer; + break; + } ++ if (count++ > TRANSFER_LIMIT) { ++ trace_usb_xhci_enforced_limit("transfers"); ++ break; ++ } + } + epctx->kick_active--; + +@@ -2618,7 +2626,7 @@ static void xhci_process_commands(XHCIState *xhci) + 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)) { +@@ -2735,6 +2743,11 @@ static void xhci_process_commands(XHCIState *xhci) + } + event.slotid = slotid; + xhci_event(xhci, &event, 0); ++ ++ if (count++ > COMMAND_LIMIT) { ++ trace_usb_xhci_enforced_limit("commands"); ++ return; ++ } + } + } + +diff --git a/hw/usb/trace-events b/hw/usb/trace-events +index fdd1d29..0c323d4 100644 +--- a/hw/usb/trace-events ++++ b/hw/usb/trace-events +@@ -174,6 +174,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" +-- +1.8.3.1 + |