From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41788) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1as5St-0002kD-SF for qemu-devel@nongnu.org; Mon, 18 Apr 2016 05:27:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1as5Sr-0007kR-Gh for qemu-devel@nongnu.org; Mon, 18 Apr 2016 05:27:31 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48965) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1as5Sr-0007gR-CB for qemu-devel@nongnu.org; Mon, 18 Apr 2016 05:27:29 -0400 From: Gerd Hoffmann Date: Mon, 18 Apr 2016 11:27:22 +0200 Message-Id: <1460971643-1499-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH 1/2] ehci: apply limit to itd/sidt descriptors List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: P J P , dushaobo@360.cn, Gerd Hoffmann 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). Unfortunaly this has two problems: First it misses the case of sitds, and second it reportly 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. Signed-off-by: Gerd Hoffmann --- hw/usb/hcd-ehci.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 159f58d..923f110 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 idt_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); + idt_count++; break; case EST_FETCHSITD: again = ehci_state_fetchsitd(ehci, async); + idt_count++; break; case EST_ADVANCEQUEUE: @@ -2092,6 +2095,11 @@ static void ehci_advance_state(EHCIState *ehci, int async) ehci_reset(ehci); again = 0; } + + /* limit the amout of idts we are willing to process each frame */ + if (idt_count > 16) { + again = 0; + } } while (again); } -- 1.8.3.1