]> git.proxmox.com Git - pve-qemu-kvm.git/commitdiff
Fix CVE-2016-4037
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Mon, 25 Apr 2016 13:08:05 +0000 (15:08 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Tue, 26 Apr 2016 13:43:23 +0000 (15:43 +0200)
usb: Infinite loop vulnerability in usb_ehci using siTD process

debian/patches/extra/CVE-2016-4037-ehci-apply-limit-to-iTD-sidt-descriptors.patch [new file with mode: 0644]
debian/patches/series

diff --git a/debian/patches/extra/CVE-2016-4037-ehci-apply-limit-to-iTD-sidt-descriptors.patch b/debian/patches/extra/CVE-2016-4037-ehci-apply-limit-to-iTD-sidt-descriptors.patch
new file mode 100644 (file)
index 0000000..cd298cd
--- /dev/null
@@ -0,0 +1,62 @@
+From 04d46122655ea02ca47a9572bcce87a23c458e9a Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Mon, 18 Apr 2016 09:11:38 +0200
+Subject: [PATCH] ehci: apply limit to iTD/sidt descriptors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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).  Unfortunately this has two problems:
+First it misses the case of siTDs, and second it reportedly 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.
+
+Reported-by: 杜少博 <dushaobo@360.cn>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/usb/hcd-ehci.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
+index 9b7ef92..99ae453 100644
+--- a/hw/usb/hcd-ehci.c
++++ b/hw/usb/hcd-ehci.c
+@@ -2009,6 +2009,7 @@ static int ehci_state_writeback(EHCIQueue *q)
+ static void ehci_advance_state(EHCIState *ehci, int async)
+ {
+     EHCIQueue *q = NULL;
++    int itd_count = 0;
+     int again;
+     do {
+@@ -2033,10 +2034,12 @@ static void ehci_advance_state(EHCIState *ehci, int async)
+         case EST_FETCHITD:
+             again = ehci_state_fetchitd(ehci, async);
++            itd_count++;
+             break;
+         case EST_FETCHSITD:
+             again = ehci_state_fetchsitd(ehci, async);
++            itd_count++;
+             break;
+         case EST_ADVANCEQUEUE:
+@@ -2085,7 +2088,8 @@ static void ehci_advance_state(EHCIState *ehci, int async)
+             break;
+         }
+-        if (again < 0) {
++        if (again < 0 || itd_count > 16) {
++            /* TODO: notify guest (raise HSE irq?) */
+             fprintf(stderr, "processing error - resetting ehci HC\n");
+             ehci_reset(ehci);
+             again = 0;
+-- 
+2.1.4
+
index 806692e8cb169ebb27e54d61a136d001e668115e..f8de9d40d40cf6539e2cf2915ea9689e2d5f8bd1 100644 (file)
@@ -53,3 +53,4 @@ extra/CVE-2016-2858-0004-rng-add-request-queue-support-to-rng-random.patch
 extra/0005-virtio-rng-ask-for-more-data-if-queue-is-not-fully-d.patch
 extra/0001-target-i386-do-not-read-write-MSR_TSC_AUX-from-KVM-i.patch
 extra/0001-i386-kvmvapic-initialise-imm32-variable.patch
 extra/0005-virtio-rng-ask-for-more-data-if-queue-is-not-fully-d.patch
 extra/0001-target-i386-do-not-read-write-MSR_TSC_AUX-from-KVM-i.patch
 extra/0001-i386-kvmvapic-initialise-imm32-variable.patch
+extra/CVE-2016-4037-ehci-apply-limit-to-iTD-sidt-descriptors.patch