]> git.proxmox.com Git - pve-qemu-kvm.git/blob - debian/patches/extra/CVE-2016-4037-ehci-apply-limit-to-iTD-sidt-descriptors.patch
Fix CVE-2016-4037
[pve-qemu-kvm.git] / debian / patches / extra / CVE-2016-4037-ehci-apply-limit-to-iTD-sidt-descriptors.patch
1 From 04d46122655ea02ca47a9572bcce87a23c458e9a Mon Sep 17 00:00:00 2001
2 From: Gerd Hoffmann <kraxel@redhat.com>
3 Date: Mon, 18 Apr 2016 09:11:38 +0200
4 Subject: [PATCH] ehci: apply limit to iTD/sidt descriptors
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Commit "156a2e4 ehci: make idt processing more robust" tries to avoid a
10 DoS by the guest (create a circular iTD queue and let qemu ehci
11 emulation run in circles forever). Unfortunately this has two problems:
12 First it misses the case of siTDs, and second it reportedly breaks
13 FreeBSD.
14
15 So lets go for a different approach: just count the number of iTDs and
16 siTDs we have seen per frame and apply a limit. That should really
17 catch all cases now.
18
19 Reported-by: 杜少博 <dushaobo@360.cn>
20 Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
21 ---
22 hw/usb/hcd-ehci.c | 6 +++++-
23 1 file changed, 5 insertions(+), 1 deletion(-)
24
25 diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
26 index 9b7ef92..99ae453 100644
27 --- a/hw/usb/hcd-ehci.c
28 +++ b/hw/usb/hcd-ehci.c
29 @@ -2009,6 +2009,7 @@ static int ehci_state_writeback(EHCIQueue *q)
30 static void ehci_advance_state(EHCIState *ehci, int async)
31 {
32 EHCIQueue *q = NULL;
33 + int itd_count = 0;
34 int again;
35
36 do {
37 @@ -2033,10 +2034,12 @@ static void ehci_advance_state(EHCIState *ehci, int async)
38
39 case EST_FETCHITD:
40 again = ehci_state_fetchitd(ehci, async);
41 + itd_count++;
42 break;
43
44 case EST_FETCHSITD:
45 again = ehci_state_fetchsitd(ehci, async);
46 + itd_count++;
47 break;
48
49 case EST_ADVANCEQUEUE:
50 @@ -2085,7 +2088,8 @@ static void ehci_advance_state(EHCIState *ehci, int async)
51 break;
52 }
53
54 - if (again < 0) {
55 + if (again < 0 || itd_count > 16) {
56 + /* TODO: notify guest (raise HSE irq?) */
57 fprintf(stderr, "processing error - resetting ehci HC\n");
58 ehci_reset(ehci);
59 again = 0;
60 --
61 2.1.4
62