summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/files/0001-kvm-iommu-CVE-2014-3601.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/files/0001-kvm-iommu-CVE-2014-3601.patch')
-rw-r--r--recipes-kernel/linux/files/0001-kvm-iommu-CVE-2014-3601.patch94
1 files changed, 94 insertions, 0 deletions
diff --git a/recipes-kernel/linux/files/0001-kvm-iommu-CVE-2014-3601.patch b/recipes-kernel/linux/files/0001-kvm-iommu-CVE-2014-3601.patch
new file mode 100644
index 0000000..e19a3c1
--- /dev/null
+++ b/recipes-kernel/linux/files/0001-kvm-iommu-CVE-2014-3601.patch
@@ -0,0 +1,94 @@
1From e35b1e9f17e0567f96502f3a2a31dace727ed3da Mon Sep 17 00:00:00 2001
2From: "Michael S. Tsirkin" <mst@redhat.com>
3Date: Tue, 19 Aug 2014 19:14:50 +0800
4Subject: [PATCH] kvm: iommu: fix the third parameter of kvm_iommu_put_pages
5 (CVE-2014-3601)
6
7commit 350b8bdd689cd2ab2c67c8a86a0be86cfa0751a7 upstream.
8
9The third parameter of kvm_iommu_put_pages is wrong,
10It should be 'gfn - slot->base_gfn'.
11
12By making gfn very large, malicious guest or userspace can cause kvm to
13go to this error path, and subsequently to pass a huge value as size.
14Alternatively if gfn is small, then pages would be pinned but never
15unpinned, causing host memory leak and local DOS.
16
17Passing a reasonable but large value could be the most dangerous case,
18because it would unpin a page that should have stayed pinned, and thus
19allow the device to DMA into arbitrary memory. However, this cannot
20happen because of the condition that can trigger the error:
21
22- out of memory (where you can't allocate even a single page)
23 should not be possible for the attacker to trigger
24
25- when exceeding the iommu's address space, guest pages after gfn
26 will also exceed the iommu's address space, and inside
27 kvm_iommu_put_pages() the iommu_iova_to_phys() will fail. The
28 page thus would not be unpinned at all.
29
30Upstream-Status: Backport
31
32Reported-by: Jack Morgenstein <jackm@mellanox.com>
33Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
34Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
35Signed-off-by: Jiri Slaby <jslaby@suse.cz>
36Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
37---
38 virt/kvm/iommu.c | 19 ++++++++++---------
39 1 file changed, 10 insertions(+), 9 deletions(-)
40
41diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
42index c329c8f..dec9971 100644
43--- a/virt/kvm/iommu.c
44+++ b/virt/kvm/iommu.c
45@@ -61,6 +61,14 @@ static pfn_t kvm_pin_pages(struct kvm_memory_slot *slot, gfn_t gfn,
46 return pfn;
47 }
48
49+static void kvm_unpin_pages(struct kvm *kvm, pfn_t pfn, unsigned long npages)
50+{
51+ unsigned long i;
52+
53+ for (i = 0; i < npages; ++i)
54+ kvm_release_pfn_clean(pfn + i);
55+}
56+
57 int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
58 {
59 gfn_t gfn, end_gfn;
60@@ -123,6 +131,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
61 if (r) {
62 printk(KERN_ERR "kvm_iommu_map_address:"
63 "iommu failed to map pfn=%llx\n", pfn);
64+ kvm_unpin_pages(kvm, pfn, page_size);
65 goto unmap_pages;
66 }
67
68@@ -134,7 +143,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
69 return 0;
70
71 unmap_pages:
72- kvm_iommu_put_pages(kvm, slot->base_gfn, gfn);
73+ kvm_iommu_put_pages(kvm, slot->base_gfn, gfn - slot->base_gfn);
74 return r;
75 }
76
77@@ -272,14 +281,6 @@ out_unlock:
78 return r;
79 }
80
81-static void kvm_unpin_pages(struct kvm *kvm, pfn_t pfn, unsigned long npages)
82-{
83- unsigned long i;
84-
85- for (i = 0; i < npages; ++i)
86- kvm_release_pfn_clean(pfn + i);
87-}
88-
89 static void kvm_iommu_put_pages(struct kvm *kvm,
90 gfn_t base_gfn, unsigned long npages)
91 {
92--
931.9.1
94