|
|
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 |
|