summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSona Sarmadi <sona.sarmadi@enea.com>2015-01-27 10:22:10 +0100
committerZhenhua Luo <zhenhua.luo@freescale.com>2015-02-03 10:05:41 +0800
commitcea3ea75de5952985a87c0039120373c20e5ed40 (patch)
tree4c26122a2c2322a91a98f9e202222d201a9899e2
parenta55ff86fcdd7210bf21162af4c5cb679d871cf4a (diff)
downloadmeta-fsl-ppc-cea3ea75de5952985a87c0039120373c20e5ed40.tar.gz
kvm-iommu: CVE-2014-3601, CVE-2014-8369
CVE-2014-3601 Fixes the third parameter of kvm_iommu_put_pages The third parameter of kvm_iommu_put_pages is wrong, It should be 'gfn - slot->base_gfn'. CVE-2014-8369 Fixes excessive pages un-pinning in kvm_iommu_map error path. (This vulnerability exists because of an incorrect fix for CVE-2014-3601 Reference: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3601 http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-8369 https://bugzilla.redhat.com/show_bug.cgi?id=1156518 https://lkml.org/lkml/2014/10/24/460 Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
-rw-r--r--recipes-kernel/linux/files/0001-kvm-iommu-CVE-2014-3601.patch94
-rw-r--r--recipes-kernel/linux/files/0002-kvm-iommu-CVE-2014-8369.patch86
-rw-r--r--recipes-kernel/linux/linux-qoriq_3.12.bb2
3 files changed, 182 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
diff --git a/recipes-kernel/linux/files/0002-kvm-iommu-CVE-2014-8369.patch b/recipes-kernel/linux/files/0002-kvm-iommu-CVE-2014-8369.patch
new file mode 100644
index 0000000..e43771c
--- /dev/null
+++ b/recipes-kernel/linux/files/0002-kvm-iommu-CVE-2014-8369.patch
@@ -0,0 +1,86 @@
1From 248541357433e3035d954435dafcdb9e70afee4e Mon Sep 17 00:00:00 2001
2From: Quentin Casasnovas <quentin.casasnovas@oracle.com>
3Date: Fri, 17 Oct 2014 22:55:59 +0200
4Subject: [PATCH] kvm: fix excessive pages un-pinning in kvm_iommu_map error
5 path.
6
7commit 3d32e4dbe71374a6780eaf51d719d76f9a9bf22f upstream.
8
9The third parameter of kvm_unpin_pages() when called from
10kvm_iommu_map_pages() is wrong, it should be the number of pages to un-pin
11and not the page size.
12
13This error was facilitated with an inconsistent API: kvm_pin_pages() takes
14a size, but kvn_unpin_pages() takes a number of pages, so fix the problem
15by matching the two.
16
17This was introduced by commit 350b8bd ("kvm: iommu: fix the third parameter
18of kvm_iommu_put_pages (CVE-2014-3601)"), which fixes the lack of
19un-pinning for pages intended to be un-pinned (i.e. memory leak) but
20unfortunately potentially aggravated the number of pages we un-pin that
21should have stayed pinned. As far as I understand though, the same
22practical mitigations apply.
23
24This issue was found during review of Red Hat 6.6 patches to prepare
25Ksplice rebootless updates.
26
27Thanks to Vegard for his time on a late Friday evening to help me in
28understanding this code.
29
30Fix for CVE-2014-8369
31
32Upstream-Status: Backport
33
34Fixes: 350b8bd ("kvm: iommu: fix the third parameter of... (CVE-2014-3601)")
35Signed-off-by: Quentin Casasnovas <quentin.casasnovas@oracle.com>
36Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
37Signed-off-by: Jamie Iles <jamie.iles@oracle.com>
38Reviewed-by: Sasha Levin <sasha.levin@oracle.com>
39Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
40Signed-off-by: Jiri Slaby <jslaby@suse.cz>
41Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
42---
43 virt/kvm/iommu.c | 8 ++++----
44 1 file changed, 4 insertions(+), 4 deletions(-)
45
46diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
47index dec9971..a650aa4 100644
48--- a/virt/kvm/iommu.c
49+++ b/virt/kvm/iommu.c
50@@ -43,13 +43,13 @@ static void kvm_iommu_put_pages(struct kvm *kvm,
51 gfn_t base_gfn, unsigned long npages);
52
53 static pfn_t kvm_pin_pages(struct kvm_memory_slot *slot, gfn_t gfn,
54- unsigned long size)
55+ unsigned long npages)
56 {
57 gfn_t end_gfn;
58 pfn_t pfn;
59
60 pfn = gfn_to_pfn_memslot(slot, gfn);
61- end_gfn = gfn + (size >> PAGE_SHIFT);
62+ end_gfn = gfn + npages;
63 gfn += 1;
64
65 if (is_error_noslot_pfn(pfn))
66@@ -119,7 +119,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
67 * Pin all pages we are about to map in memory. This is
68 * important because we unmap and unpin in 4kb steps later.
69 */
70- pfn = kvm_pin_pages(slot, gfn, page_size);
71+ pfn = kvm_pin_pages(slot, gfn, page_size >> PAGE_SHIFT);
72 if (is_error_noslot_pfn(pfn)) {
73 gfn += 1;
74 continue;
75@@ -131,7 +131,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
76 if (r) {
77 printk(KERN_ERR "kvm_iommu_map_address:"
78 "iommu failed to map pfn=%llx\n", pfn);
79- kvm_unpin_pages(kvm, pfn, page_size);
80+ kvm_unpin_pages(kvm, pfn, page_size >> PAGE_SHIFT);
81 goto unmap_pages;
82 }
83
84--
851.9.1
86
diff --git a/recipes-kernel/linux/linux-qoriq_3.12.bb b/recipes-kernel/linux/linux-qoriq_3.12.bb
index 195b477..5993b59 100644
--- a/recipes-kernel/linux/linux-qoriq_3.12.bb
+++ b/recipes-kernel/linux/linux-qoriq_3.12.bb
@@ -17,6 +17,8 @@ SRC_URI = "git://git.freescale.com/ppc/sdk/linux.git;nobranch=1 \
17 file://0002-HID-CVE-2014-3182.patch \ 17 file://0002-HID-CVE-2014-3182.patch \
18 file://0003-HID-CVE-2014-3184.patch \ 18 file://0003-HID-CVE-2014-3184.patch \
19 file://0004-USB-CVE-2014-3185.patch \ 19 file://0004-USB-CVE-2014-3185.patch \
20 file://0001-kvm-iommu-CVE-2014-3601.patch \
21 file://0002-kvm-iommu-CVE-2014-8369.patch \
20" 22"
21SRCREV = "6619b8b55796cdf0cec04b66a71288edd3057229" 23SRCREV = "6619b8b55796cdf0cec04b66a71288edd3057229"
22 24