Blame SOURCES/CVE-2021-22543.patch

da2c8e
From 710481f30b26856f462d3e5923bf69b32c12e097 Mon Sep 17 00:00:00 2001
da2c8e
From: Artem Savkov <asavkov@redhat.com>
da2c8e
Date: Fri, 3 Sep 2021 16:00:17 +0200
da2c8e
Subject: [KPATCH CVE-2021-22543] KVM: do not allow mapping valid but
da2c8e
 non-reference-counted pages
da2c8e
da2c8e
Kernels:
da2c8e
3.10.0-1160.el7
da2c8e
3.10.0-1160.2.1.el7
da2c8e
3.10.0-1160.2.2.el7
da2c8e
3.10.0-1160.6.1.el7
da2c8e
3.10.0-1160.11.1.el7
da2c8e
3.10.0-1160.15.2.el7
da2c8e
3.10.0-1160.21.1.el7
da2c8e
3.10.0-1160.24.1.el7
da2c8e
3.10.0-1160.25.1.el7
da2c8e
3.10.0-1160.31.1.el7
da2c8e
3.10.0-1160.36.2.el7
da2c8e
3.10.0-1160.41.1.el7
da2c8e
da2c8e
Changes since last build:
da2c8e
[x86_64]:
da2c8e
kvm_main.o: changed function: __gfn_to_pfn_memslot
da2c8e
da2c8e
[ppc64le]:
da2c8e
kvm_main.o: changed function: gfn_to_page
da2c8e
kvm_main.o: changed function: gfn_to_pfn
da2c8e
kvm_main.o: changed function: gfn_to_pfn_memslot
da2c8e
kvm_main.o: changed function: gfn_to_pfn_prot
da2c8e
kvm_main.o: changed function: hva_to_pfn
da2c8e
kvm_main.o: changed function: kvm_vcpu_gfn_to_page
da2c8e
kvm_main.o: changed function: kvm_vcpu_gfn_to_pfn
da2c8e
da2c8e
---------------------------
da2c8e
da2c8e
Kernels:
da2c8e
3.10.0-1160.2.1.el7
da2c8e
3.10.0-1160.2.2.el7
da2c8e
3.10.0-1160.6.1.el7
da2c8e
3.10.0-1160.11.1.el7
da2c8e
3.10.0-1160.15.2.el7
da2c8e
3.10.0-1160.21.1.el7
da2c8e
3.10.0-1160.24.1.el7
da2c8e
3.10.0-1160.25.1.el7
da2c8e
3.10.0-1160.31.1.el7
da2c8e
3.10.0-1160.36.2.el7
da2c8e
3.10.0-1160.41.1.el7
da2c8e
3.10.0-1160.42.2.el7
da2c8e
da2c8e
Modifications: none
da2c8e
Kpatch-MR: https://gitlab.com/kpatch-dev/rhel-7/-/merge_requests/7
da2c8e
Approved-by: Yannick Cote (@ycote1)
da2c8e
Approved-by: Joe Lawrence (@joe.lawrence)
da2c8e
Z-MR: https://gitlab.com/redhat/rhel/src/kernel/rhel-7/-/merge_requests/259
da2c8e
da2c8e
commit 64b6dd5036622d9fab20cea237ae19402a1a2ee3
da2c8e
Author: Jon Maloy <jmaloy@redhat.com>
da2c8e
Date:   Tue Jul 13 15:28:38 2021 -0400
da2c8e
da2c8e
    KVM: do not allow mapping valid but non-reference-counted pages
da2c8e
da2c8e
    Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1975511
da2c8e
    Upstream: commit f8be156be163a052a067306417cd0ff679068c97
da2c8e
    CVE-2021-22543
da2c8e
    Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=39156005
da2c8e
    Conflicts: The upstream version hva_to_pfn_remapped() has been upgraded
da2c8e
               with lock support and a 'writeable' parameter. Those changes
da2c8e
               entail a code conflict, but not functional conflict, with
da2c8e
               this commit.
da2c8e
da2c8e
    commit f8be156be163a052a067306417cd0ff679068c97
da2c8e
    Author: Nicholas Piggin <npiggin@gmail.com>
da2c8e
    Date:   Thu Jun 24 08:29:04 2021 -0400
da2c8e
da2c8e
        KVM: do not allow mapping valid but non-reference-counted pages
da2c8e
da2c8e
        It's possible to create a region which maps valid but non-refcounted
da2c8e
        pages (e.g., tail pages of non-compound higher order allocations). These
da2c8e
        host pages can then be returned by gfn_to_page, gfn_to_pfn, etc., family
da2c8e
        of APIs, which take a reference to the page, which takes it from 0 to 1.
da2c8e
        When the reference is dropped, this will free the page incorrectly.
da2c8e
da2c8e
        Fix this by only taking a reference on valid pages if it was non-zero,
da2c8e
        which indicates it is participating in normal refcounting (and can be
da2c8e
        released with put_page).
da2c8e
da2c8e
        This addresses CVE-2021-22543.
da2c8e
da2c8e
        Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
da2c8e
        Tested-by: Paolo Bonzini <pbonzini@redhat.com>
da2c8e
        Cc: stable@vger.kernel.org
da2c8e
        Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
da2c8e
da2c8e
    Signed-off-by: Jon Maloy <jmaloy@redhat.com>
da2c8e
da2c8e
Signed-off-by: Artem Savkov <asavkov@redhat.com>
da2c8e
---
da2c8e
 virt/kvm/kvm_main.c | 21 ++++++++++++++++++---
da2c8e
 1 file changed, 18 insertions(+), 3 deletions(-)
da2c8e
da2c8e
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
da2c8e
index 4b01a017b262..2f40d5fe257d 100644
da2c8e
--- a/virt/kvm/kvm_main.c
da2c8e
+++ b/virt/kvm/kvm_main.c
da2c8e
@@ -1479,6 +1479,13 @@ static bool vma_is_valid(struct vm_area_struct *vma, bool write_fault)
da2c8e
 	return true;
da2c8e
 }
da2c8e
 
da2c8e
+static int kvm_try_get_pfn(kvm_pfn_t pfn)
da2c8e
+{
da2c8e
+	if (kvm_is_reserved_pfn(pfn))
da2c8e
+		return 1;
da2c8e
+	return get_page_unless_zero(pfn_to_page(pfn));
da2c8e
+}
da2c8e
+
da2c8e
 static int hva_to_pfn_remapped(struct vm_area_struct *vma,
da2c8e
 			       unsigned long addr, bool *async,
da2c8e
 			       bool write_fault, kvm_pfn_t *p_pfn)
da2c8e
@@ -1514,11 +1521,19 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma,
da2c8e
 	 * Whoever called remap_pfn_range is also going to call e.g.
da2c8e
 	 * unmap_mapping_range before the underlying pages are freed,
da2c8e
 	 * causing a call to our MMU notifier.
da2c8e
-	 */ 
da2c8e
-	kvm_get_pfn(pfn);
da2c8e
+	 *
da2c8e
+	 * Certain IO or PFNMAP mappings can be backed with valid
da2c8e
+	 * struct pages, but be allocated without refcounting e.g.,
da2c8e
+	 * tail pages of non-compound higher order allocations, which
da2c8e
+	 * would then underflow the refcount when the caller does the
da2c8e
+	 * required put_page. Don't allow those pages here.
da2c8e
+	 */
da2c8e
 
da2c8e
+	if (!kvm_try_get_pfn(pfn))
da2c8e
+		r = -EFAULT;
da2c8e
 	*p_pfn = pfn;
da2c8e
-	return 0;
da2c8e
+
da2c8e
+	return r;
da2c8e
 }
da2c8e
 
da2c8e
 /*
da2c8e
-- 
da2c8e
2.26.3
da2c8e
da2c8e