aboutsummaryrefslogtreecommitdiff
path: root/gnu/packages/patches/qemu-CVE-2016-8576.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/packages/patches/qemu-CVE-2016-8576.patch')
-rw-r--r--gnu/packages/patches/qemu-CVE-2016-8576.patch62
1 files changed, 62 insertions, 0 deletions
diff --git a/gnu/packages/patches/qemu-CVE-2016-8576.patch b/gnu/packages/patches/qemu-CVE-2016-8576.patch
new file mode 100644
index 0000000000..5031b59d81
--- /dev/null
+++ b/gnu/packages/patches/qemu-CVE-2016-8576.patch
@@ -0,0 +1,62 @@
+From 20009bdaf95d10bf748fa69b104672d3cfaceddf Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Fri, 7 Oct 2016 10:15:29 +0200
+Subject: [PATCH] xhci: limit the number of link trbs we are willing to process
+
+Signed-off-by: Gerd Hoffmann <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
+