From 0ef3b0b83d5559ff430d64ca3297eecbdd2e15cc Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Mon, 25 Apr 2016 15:08:05 +0200 Subject: [PATCH] Fix CVE-2016-4037 usb: Infinite loop vulnerability in usb_ehci using siTD process --- ...-apply-limit-to-iTD-sidt-descriptors.patch | 62 +++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 63 insertions(+) create mode 100644 debian/patches/extra/CVE-2016-4037-ehci-apply-limit-to-iTD-sidt-descriptors.patch 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 index 0000000..cd298cd --- /dev/null +++ b/debian/patches/extra/CVE-2016-4037-ehci-apply-limit-to-iTD-sidt-descriptors.patch @@ -0,0 +1,62 @@ +From 04d46122655ea02ca47a9572bcce87a23c458e9a Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +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: 杜少博 +Signed-off-by: Gerd Hoffmann +--- + 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 + diff --git a/debian/patches/series b/debian/patches/series index 806692e..f8de9d4 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -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/CVE-2016-4037-ehci-apply-limit-to-iTD-sidt-descriptors.patch -- 2.39.2