|
|
83d96c |
From 9cb8a03ebca7263af03701ef256248ca8e5c434d Mon Sep 17 00:00:00 2001
|
|
|
83d96c |
From: Artem Savkov <asavkov@redhat.com>
|
|
|
83d96c |
Date: Wed, 7 Jul 2021 17:44:40 +0200
|
|
|
83d96c |
Subject: [PATCH] KVM: do not allow mapping valid but non-reference-counted
|
|
|
83d96c |
pages
|
|
|
83d96c |
|
|
|
83d96c |
Kernels:
|
|
|
83d96c |
4.18.0-305.el8
|
|
|
83d96c |
4.18.0-305.3.1.el8_4
|
|
|
83d96c |
4.18.0-305.7.1.el8_4
|
|
|
83d96c |
|
|
|
83d96c |
Changes since last build:
|
|
|
83d96c |
[x86_64]:
|
|
|
83d96c |
kvm_main.o: changed function: __gfn_to_pfn_memslot
|
|
|
83d96c |
|
|
|
83d96c |
[ppc64le]:
|
|
|
83d96c |
kvm_main.o: changed function: gfn_to_pfn_memslot
|
|
|
83d96c |
kvm_main.o: changed function: hva_to_pfn
|
|
|
83d96c |
|
|
|
83d96c |
---------------------------
|
|
|
83d96c |
|
|
|
83d96c |
Kernels:
|
|
|
83d96c |
4.18.0-305.el8
|
|
|
83d96c |
4.18.0-305.3.1.el8_4
|
|
|
83d96c |
4.18.0-305.7.1.el8_4
|
|
|
83d96c |
4.18.0-305.10.2.el8_4
|
|
|
83d96c |
|
|
|
83d96c |
Modifications: none
|
|
|
83d96c |
Z-MR: https://gitlab.com/redhat/rhel/src/kernel/rhel-8/-/merge_requests/898
|
|
|
83d96c |
Testing: kernel_write.c reproducer
|
|
|
83d96c |
|
|
|
83d96c |
commit 9871aa051ac11ab8551be01d7394915a5530dbbd
|
|
|
83d96c |
Author: Jon Maloy <jmaloy@redhat.com>
|
|
|
83d96c |
Date: Wed Jun 30 21:09:40 2021 -0400
|
|
|
83d96c |
|
|
|
83d96c |
KVM: do not allow mapping valid but non-reference-counted pages
|
|
|
83d96c |
|
|
|
83d96c |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1975514
|
|
|
83d96c |
Upstream: commit f8be156be163a052a067306417cd0ff679068c97
|
|
|
83d96c |
CVE: CVE-2021-22543
|
|
|
83d96c |
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=37829337
|
|
|
83d96c |
|
|
|
83d96c |
commit f8be156be163a052a067306417cd0ff679068c97
|
|
|
83d96c |
Author: Nicholas Piggin <npiggin@gmail.com>
|
|
|
83d96c |
Date: Thu Jun 24 08:29:04 2021 -0400
|
|
|
83d96c |
|
|
|
83d96c |
KVM: do not allow mapping valid but non-reference-counted pages
|
|
|
83d96c |
|
|
|
83d96c |
It's possible to create a region which maps valid but non-refcounted
|
|
|
83d96c |
pages (e.g., tail pages of non-compound higher order allocations). These
|
|
|
83d96c |
host pages can then be returned by gfn_to_page, gfn_to_pfn, etc., family
|
|
|
83d96c |
of APIs, which take a reference to the page, which takes it from 0 to 1.
|
|
|
83d96c |
When the reference is dropped, this will free the page incorrectly.
|
|
|
83d96c |
|
|
|
83d96c |
Fix this by only taking a reference on valid pages if it was non-zero,
|
|
|
83d96c |
which indicates it is participating in normal refcounting (and can be
|
|
|
83d96c |
released with put_page).
|
|
|
83d96c |
|
|
|
83d96c |
This addresses CVE-2021-22543.
|
|
|
83d96c |
|
|
|
83d96c |
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
|
|
|
83d96c |
Tested-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
83d96c |
Cc: stable@vger.kernel.org
|
|
|
83d96c |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
83d96c |
|
|
|
83d96c |
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
|
|
|
83d96c |
|
|
|
83d96c |
Signed-off-by: Artem Savkov <asavkov@redhat.com>
|
|
|
83d96c |
Acked-by: Yannick Cote <ycote@redhat.com>
|
|
|
83d96c |
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
|
|
|
83d96c |
---
|
|
|
83d96c |
virt/kvm/kvm_main.c | 19 +++++++++++++++++--
|
|
|
83d96c |
1 file changed, 17 insertions(+), 2 deletions(-)
|
|
|
83d96c |
|
|
|
83d96c |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
|
|
|
83d96c |
index d4ec73c304a31..9f1cf429954c7 100644
|
|
|
83d96c |
--- a/virt/kvm/kvm_main.c
|
|
|
83d96c |
+++ b/virt/kvm/kvm_main.c
|
|
|
83d96c |
@@ -1894,6 +1894,13 @@ static bool vma_is_valid(struct vm_area_struct *vma, bool write_fault)
|
|
|
83d96c |
return true;
|
|
|
83d96c |
}
|
|
|
83d96c |
|
|
|
83d96c |
+static int kvm_try_get_pfn(kvm_pfn_t pfn)
|
|
|
83d96c |
+{
|
|
|
83d96c |
+ if (kvm_is_reserved_pfn(pfn))
|
|
|
83d96c |
+ return 1;
|
|
|
83d96c |
+ return get_page_unless_zero(pfn_to_page(pfn));
|
|
|
83d96c |
+}
|
|
|
83d96c |
+
|
|
|
83d96c |
static int hva_to_pfn_remapped(struct vm_area_struct *vma,
|
|
|
83d96c |
unsigned long addr, bool *async,
|
|
|
83d96c |
bool write_fault, bool *writable,
|
|
|
83d96c |
@@ -1936,11 +1943,19 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma,
|
|
|
83d96c |
* Whoever called remap_pfn_range is also going to call e.g.
|
|
|
83d96c |
* unmap_mapping_range before the underlying pages are freed,
|
|
|
83d96c |
* causing a call to our MMU notifier.
|
|
|
83d96c |
+ *
|
|
|
83d96c |
+ * Certain IO or PFNMAP mappings can be backed with valid
|
|
|
83d96c |
+ * struct pages, but be allocated without refcounting e.g.,
|
|
|
83d96c |
+ * tail pages of non-compound higher order allocations, which
|
|
|
83d96c |
+ * would then underflow the refcount when the caller does the
|
|
|
83d96c |
+ * required put_page. Don't allow those pages here.
|
|
|
83d96c |
*/
|
|
|
83d96c |
- kvm_get_pfn(pfn);
|
|
|
83d96c |
+ if (!kvm_try_get_pfn(pfn))
|
|
|
83d96c |
+ r = -EFAULT;
|
|
|
83d96c |
|
|
|
83d96c |
*p_pfn = pfn;
|
|
|
83d96c |
- return 0;
|
|
|
83d96c |
+
|
|
|
83d96c |
+ return r;
|
|
|
83d96c |
}
|
|
|
83d96c |
|
|
|
83d96c |
/*
|
|
|
83d96c |
--
|
|
|
83d96c |
2.26.3
|
|
|
83d96c |
|