986c2ac
From 95ed56939eb2eaa4e2f349fe6dcd13ca4edfd8fb Mon Sep 17 00:00:00 2001
986c2ac
From: Li Qiang <liqiang6-s@360.cn>
986c2ac
Date: Tue, 7 Feb 2017 02:23:33 -0800
986c2ac
Subject: [PATCH] usb: ohci: limit the number of link eds
986c2ac
986c2ac
The guest may builds an infinite loop with link eds. This patch
986c2ac
limit the number of linked ed to avoid this.
986c2ac
986c2ac
Signed-off-by: Li Qiang <liqiang6-s@360.cn>
986c2ac
Message-id: 5899a02e.45ca240a.6c373.93c1@mx.google.com
986c2ac
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
986c2ac
---
986c2ac
 hw/usb-ohci.c | 9 ++++++++-
986c2ac
 1 file changed, 8 insertions(+), 1 deletion(-)
986c2ac
986c2ac
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
986c2ac
index 2cba3e3..21c93e0 100644
986c2ac
--- a/hw/usb-ohci.c
986c2ac
+++ b/hw/usb-ohci.c
986c2ac
@@ -42,6 +42,8 @@
986c2ac
 
986c2ac
 #define OHCI_MAX_PORTS 15
986c2ac
 
986c2ac
+#define ED_LINK_LIMIT 4
986c2ac
+
986c2ac
 static int64_t usb_frame_time;
986c2ac
 static int64_t usb_bit_time;
986c2ac
 
986c2ac
@@ -1184,7 +1186,7 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
986c2ac
     uint32_t next_ed;
986c2ac
     uint32_t cur;
986c2ac
     int active;
986c2ac
-
986c2ac
+    uint32_t link_cnt = 0;
986c2ac
     active = 0;
986c2ac
 
986c2ac
     if (head == 0)
986c2ac
@@ -1199,6 +1201,10 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
986c2ac
 
986c2ac
         next_ed = ed.next & OHCI_DPTR_MASK;
986c2ac
 
986c2ac
+        if (++link_cnt > ED_LINK_LIMIT) {
986c2ac
+            return 0;
986c2ac
+        }
986c2ac
+
986c2ac
         if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) {
986c2ac
             uint32_t addr;
986c2ac
             /* Cancel pending packets for ED that have been paused.  */
986c2ac
-- 
986c2ac
1.8.3.1
986c2ac