f3149d8
------------------------------------------------------------------------
f3149d8
*From*: 	Gerd Hoffmann
f3149d8
*Subject*: 	[Qemu-devel] [PATCH 1/2] ehci: apply limit to itd/sidt
f3149d8
descriptors
f3149d8
*Date*: 	Mon, 18 Apr 2016 11:27:22 +0200
f3149d8
f3149d8
------------------------------------------------------------------------
f3149d8
f3149d8
Commit "156a2e4 ehci: make idt processing more robust" tries to avoid a
f3149d8
DoS by the guest (create a circular itd queue and let qemu ehci
f3149d8
emulation run in circles forever).  Unfortunaly this has two problems:
f3149d8
First it misses the case of sitds, and second it reportly breaks
f3149d8
freebsd.
f3149d8
f3149d8
So lets go for a different approach: just count the number of itds and
f3149d8
sitds we have seen per frame and apply a limit.  That should really
f3149d8
catch all cases now.
f3149d8
f3149d8
Signed-off-by: Gerd Hoffmann <address@hidden>
f3149d8
---
f3149d8
 hw/usb/hcd-ehci.c | 8 ++++++++
f3149d8
 1 file changed, 8 insertions(+)
f3149d8
f3149d8
diff --git a/tools/qemu-xen/hw/usb/hcd-ehci.c b/tools/qemu-xen/hw/usb/hcd-ehci.c
f3149d8
index 159f58d..923f110 100644
f3149d8
--- a/tools/qemu-xen/hw/usb/hcd-ehci.c
f3149d8
+++ b/tools/qemu-xen/hw/usb/hcd-ehci.c
f3149d8
@@ -2011,6 +2011,7 @@ static int ehci_state_writeback(EHCIQueue *q)
f3149d8
 static void ehci_advance_state(EHCIState *ehci, int async)
f3149d8
 {
f3149d8
     EHCIQueue *q = NULL;
f3149d8
+    int idt_count = 0;
f3149d8
     int again;
f3149d8
 
f3149d8
     do {
f3149d8
@@ -2035,10 +2036,12 @@ static void ehci_advance_state(EHCIState *ehci, int async)
f3149d8
 
f3149d8
         case EST_FETCHITD:
f3149d8
             again = ehci_state_fetchitd(ehci, async);
f3149d8
+            idt_count++;
f3149d8
             break;
f3149d8
 
f3149d8
         case EST_FETCHSITD:
f3149d8
             again = ehci_state_fetchsitd(ehci, async);
f3149d8
+            idt_count++;
f3149d8
             break;
f3149d8
 
f3149d8
         case EST_ADVANCEQUEUE:
f3149d8
@@ -2092,6 +2095,11 @@ static void ehci_advance_state(EHCIState *ehci, int async)
f3149d8
             ehci_reset(ehci);
f3149d8
             again = 0;
f3149d8
         }
f3149d8
+
f3149d8
+        /* limit the amout of idts we are willing to process each frame */
f3149d8
+        if (idt_count > 16) {
f3149d8
+            again = 0;
f3149d8
+        }
f3149d8
     }
f3149d8
     while (again);
f3149d8
 }
f3149d8
-- 
f3149d8
1.8.3.1
f3149d8