https://bugs.gentoo.org/580426 https://bugs.gentoo.org/568246 From a49923d2837d20510d645d3758f1ad87c32d0730 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 18 Apr 2016 09:20:54 +0200 Subject: [PATCH] Revert "ehci: make idt processing more robust" This reverts commit 156a2e4dbffa85997636a7a39ef12da6f1b40254. Breaks FreeBSD. Signed-off-by: Gerd Hoffmann --- hw/usb/hcd-ehci.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index d5c0e1c..43a8f7a 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -1397,7 +1397,7 @@ static int ehci_process_itd(EHCIState *ehci, { USBDevice *dev; USBEndpoint *ep; - uint32_t i, len, pid, dir, devaddr, endp, xfers = 0; + uint32_t i, len, pid, dir, devaddr, endp; uint32_t pg, off, ptr1, ptr2, max, mult; ehci->periodic_sched_active = PERIODIC_ACTIVE; @@ -1489,10 +1489,9 @@ static int ehci_process_itd(EHCIState *ehci, ehci_raise_irq(ehci, USBSTS_INT); } itd->transact[i] &= ~ITD_XACT_ACTIVE; - xfers++; } } - return xfers ? 0 : -1; + return 0; } -- 2.7.4 From 1ae3f2f178087711f9591350abad133525ba93f2 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 18 Apr 2016 09:11:38 +0200 Subject: [PATCH] ehci: apply limit to iTD/sidt descriptors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit "156a2e4 ehci: make idt processing more robust" tries to avoid a DoS by the guest (create a circular iTD queue and let qemu ehci emulation run in circles forever). Unfortunately this has two problems: First it misses the case of siTDs, and second it reportedly breaks FreeBSD. So lets go for a different approach: just count the number of iTDs and siTDs we have seen per frame and apply a limit. That should really catch all cases now. Reported-by: 杜少博 Signed-off-by: Gerd Hoffmann --- hw/usb/hcd-ehci.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 159f58d..d5c0e1c 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -2011,6 +2011,7 @@ static int ehci_state_writeback(EHCIQueue *q) static void ehci_advance_state(EHCIState *ehci, int async) { EHCIQueue *q = NULL; + int itd_count = 0; int again; do { @@ -2035,10 +2036,12 @@ static void ehci_advance_state(EHCIState *ehci, int async) case EST_FETCHITD: again = ehci_state_fetchitd(ehci, async); + itd_count++; break; case EST_FETCHSITD: again = ehci_state_fetchsitd(ehci, async); + itd_count++; break; case EST_ADVANCEQUEUE: @@ -2087,7 +2090,8 @@ static void ehci_advance_state(EHCIState *ehci, int async) break; } - if (again < 0) { + if (again < 0 || itd_count > 16) { + /* TODO: notify guest (raise HSE irq?) */ fprintf(stderr, "processing error - resetting ehci HC\n"); ehci_reset(ehci); again = 0; -- 2.7.4