From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43206) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1buJ78-0003EP-H8 for qemu-devel@nongnu.org; Wed, 12 Oct 2016 08:58:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1buJ73-0005xN-H9 for qemu-devel@nongnu.org; Wed, 12 Oct 2016 08:58:29 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48824) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1buJ73-0005v8-Bs for qemu-devel@nongnu.org; Wed, 12 Oct 2016 08:58:25 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 49C867F3EB for ; Wed, 12 Oct 2016 12:58:23 +0000 (UTC) From: Gerd Hoffmann Date: Wed, 12 Oct 2016 14:58:08 +0200 Message-Id: <1476277098-29570-2-git-send-email-kraxel@redhat.com> In-Reply-To: <1476277098-29570-1-git-send-email-kraxel@redhat.com> References: <1476277098-29570-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PULL 01/11] xhci: limit the number of link trbs we are willing to process List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann Needed to avoid we run in circles forever in case the guest builds an endless loop with link trbs. Reported-by: Li Qiang Tested-by: P J P Signed-off-by: Gerd Hoffmann Message-id: 1476096382-7981-1-git-send-email-kraxel@redhat.com --- hw/usb/hcd-xhci.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 726435c..ee4fa48 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -54,6 +54,8 @@ * to the specs when it gets them */ #define ER_FULL_HACK +#define TRB_LINK_LIMIT 4 + #define LEN_CAP 0x40 #define LEN_OPER (0x400 + 0x10 * MAXPORTS) #define LEN_RUNTIME ((MAXINTRS + 1) * 0x20) @@ -1000,6 +1002,7 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb, dma_addr_t *addr) { PCIDevice *pci_dev = PCI_DEVICE(xhci); + uint32_t link_cnt = 0; while (1) { TRBType type; @@ -1026,6 +1029,9 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb, ring->dequeue += TRB_SIZE; return type; } else { + if (++link_cnt > TRB_LINK_LIMIT) { + return 0; + } ring->dequeue = xhci_mask64(trb->parameter); if (trb->control & TRB_LK_TC) { ring->ccs = !ring->ccs; @@ -1043,6 +1049,7 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) bool ccs = ring->ccs; /* hack to bundle together the two/three TDs that make a setup transfer */ bool control_td_set = 0; + uint32_t link_cnt = 0; while (1) { TRBType type; @@ -1058,6 +1065,9 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) type = TRB_TYPE(trb); if (type == TR_LINK) { + if (++link_cnt > TRB_LINK_LIMIT) { + return -length; + } dequeue = xhci_mask64(trb.parameter); if (trb.control & TRB_LK_TC) { ccs = !ccs; -- 1.8.3.1