Add KVM hugepage recovery memslot bounds fix (upstream ef057cbf825e); bump to 553.139.4
This commit is contained in:
parent
9787fb255b
commit
411bc6b502
134
SOURCES/1101-kvm-x86-mmu-ensure-hugepage-is-in-by-slot.patch
Normal file
134
SOURCES/1101-kvm-x86-mmu-ensure-hugepage-is-in-by-slot.patch
Normal file
@ -0,0 +1,134 @@
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Fri, 26 Jun 2026 19:46:19 +0200
|
||||
Subject: KVM: x86/mmu: Ensure hugepage is in by slot before checking max mapping level
|
||||
|
||||
From: Sean Christopherson <seanjc@google.com>
|
||||
|
||||
commit ef057cbf825e03b63f6edf5980f96abf3c53089d upstream.
|
||||
|
||||
When recovering hugepages in the shadow MMU, verify that the base gfn of
|
||||
the shadow page is actually contained within the target memslot, *before*
|
||||
querying the max mapping level given the shadow page's gfn. Failure to
|
||||
pre-check the validity of the gfn can lead to an out-of-bounds access to
|
||||
the slot's lpage_info (which typically manifests as a host #PF because the
|
||||
lpage_info is vmalloc'd) if the guest creates a hugepage mapping (in its
|
||||
PTEs) that extends "below" the bounds of a memslot.
|
||||
|
||||
When faulting in memory for a guest, and the size of the guest mapping is
|
||||
greater than KVM's (current) max mapping, then KVM will create a "direct"
|
||||
shadow page (direct in that there are no gPTEs to shadow, and so the target
|
||||
gfn is a direct calculation given the base gfn of the shadow page). The
|
||||
hugepage recovery flow looks for such direct shadow pages, as forcing 4KiB
|
||||
mappings when dirty logging generates the guest > host mapping size case.
|
||||
When the 4KiB restriction is lifted, then KVM can replace the shadow page
|
||||
with a hugepage.
|
||||
|
||||
But if KVM originally used a smaller mapping than the guest because the
|
||||
range of memory covered by the guest hugepage exceeds the bounds of a
|
||||
memslot, then KVM will link a direct shadow page with a gfn that is outside
|
||||
the bounds of the memslot being used to fault in memory. The rmap entry
|
||||
added for the leaf mapping is correct and within bounds, but the gfn of the
|
||||
leaf SPTE's parent shadow page will be out of bounds.
|
||||
|
||||
BUG: unable to handle page fault for address: ffffc90000806ffc
|
||||
#PF: supervisor read access in kernel mode
|
||||
#PF: error_code(0x0000) - not-present page
|
||||
PGD 100000067 P4D 100000067 PUD 1002a7067 PMD 10612f067 PTE 0
|
||||
Oops: Oops: 0000 [#1] SMP
|
||||
CPU: 13 UID: 1000 PID: 757 Comm: mmu_stress_test Not tainted 7.1.0-rc1-48ce1e26eace-x86_pir_to_irr_comments-vm #341 PREEMPT
|
||||
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
|
||||
RIP: 0010:kvm_mmu_max_mapping_level+0x79/0x2b0 [kvm]
|
||||
Call Trace:
|
||||
<TASK>
|
||||
kvm_mmu_recover_huge_pages+0x21b/0x320 [kvm]
|
||||
kvm_set_memslot+0x1ee/0x590 [kvm]
|
||||
kvm_set_memory_region.part.0+0x3a1/0x4d0 [kvm]
|
||||
kvm_vm_ioctl+0x9bf/0x15d0 [kvm]
|
||||
__x64_sys_ioctl+0x8a/0xd0
|
||||
do_syscall_64+0xb7/0xbb0
|
||||
entry_SYSCALL_64_after_hwframe+0x4b/0x53
|
||||
RIP: 0033:0x7f21c0f1a9bf
|
||||
</TASK>
|
||||
|
||||
Don't bother pre-checking the bounds of the potential hugepage, i.e. don't
|
||||
check that e.g. sp->gfn + KVM_PAGES_PER_HPAGE(sp->role.level + 1) is also
|
||||
within the memslot, as the checks performed by kvm_mmu_max_mapping_level()
|
||||
are a superset of the basic bounds checks. I.e. pre-checking the full
|
||||
range would be a dubious micro-optimization.
|
||||
|
||||
Fixes: 9eba50f8d7fc ("KVM: x86/mmu: Consult max mapping level when zapping collapsible SPTEs")
|
||||
Cc: stable@vger.kernel.org
|
||||
Cc: David Matlack <dmatlack@google.com>
|
||||
Cc: James Houghton <jthoughton@google.com>
|
||||
Cc: Alexander Bulekov <bkov@amazon.com>
|
||||
Cc: Fred Griffoul <fgriffo@amazon.co.uk>
|
||||
Cc: Alexander Graf <graf@amazon.de>
|
||||
Cc: David Woodhouse <dwmw@amazon.co.uk>
|
||||
Cc: Filippo Sironi <sironi@amazon.de>
|
||||
Cc: Ivan Orlov <iorlov@amazon.co.uk>
|
||||
Signed-off-by: Sean Christopherson <seanjc@google.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
arch/x86/kvm/mmu/mmu.c | 19 +++++++++++++------
|
||||
include/linux/kvm_host.h | 7 ++++++-
|
||||
2 files changed, 19 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
|
||||
index 9597112..12d3e1f 100644
|
||||
--- a/arch/x86/kvm/mmu/mmu.c
|
||||
+++ b/arch/x86/kvm/mmu/mmu.c
|
||||
@@ -6045,13 +6045,20 @@ restart:
|
||||
pfn = spte_to_pfn(*sptep);
|
||||
|
||||
/*
|
||||
- * We cannot do huge page mapping for indirect shadow pages,
|
||||
- * which are found on the last rmap (level = 1) when not using
|
||||
- * tdp; such shadow pages are synced with the page table in
|
||||
- * the guest, and the guest page table is using 4K page size
|
||||
- * mapping if the indirect sp has level = 1.
|
||||
+ * Direct shadow page can be replaced by a hugepage if the host
|
||||
+ * mapping level allows it and the memslot maps all of the host
|
||||
+ * hugepage. Note! If the memslot maps only part of the
|
||||
+ * hugepage, sp->gfn may be below slot->base_gfn, and querying
|
||||
+ * the max mapping level would cause an out-of-bounds lpage_info
|
||||
+ * access. So the gfn bounds check *must* be done first.
|
||||
+ *
|
||||
+ * Indirect shadow pages are created when the guest page tables
|
||||
+ * are using 4K pages. Since the host mapping is always
|
||||
+ * constrained by the page size in the guest, indirect shadow
|
||||
+ * pages are never collapsible.
|
||||
*/
|
||||
- if (sp->role.direct && !kvm_is_reserved_pfn(pfn) &&
|
||||
+ if (sp->role.direct && is_gfn_in_memslot(slot, sp->gfn) &&
|
||||
+ !kvm_is_reserved_pfn(pfn) &&
|
||||
sp->role.level < kvm_mmu_max_mapping_level(kvm, slot, sp->gfn,
|
||||
pfn, PG_LEVEL_NUM)) {
|
||||
pte_list_remove(kvm, rmap_head, sptep);
|
||||
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
|
||||
index eaebea6..c37570a 100644
|
||||
--- a/include/linux/kvm_host.h
|
||||
+++ b/include/linux/kvm_host.h
|
||||
@@ -1378,6 +1378,11 @@ static inline struct rcuwait *kvm_arch_vcpu_get_wait(struct kvm_vcpu *vcpu)
|
||||
#endif
|
||||
}
|
||||
|
||||
+static inline bool is_gfn_in_memslot(const struct kvm_memory_slot *slot, gfn_t gfn)
|
||||
+{
|
||||
+ return gfn >= slot->base_gfn && gfn < slot->base_gfn + slot->npages;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Wake a vCPU if necessary, but don't do any stats/metadata updates. Returns
|
||||
* true if the vCPU was blocking and was awakened, false otherwise.
|
||||
@@ -1464,7 +1469,7 @@ try_get_memslot(struct kvm_memory_slot *slot, gfn_t gfn)
|
||||
if (!slot)
|
||||
return NULL;
|
||||
|
||||
- if (gfn >= slot->base_gfn && gfn < slot->base_gfn + slot->npages)
|
||||
+ if (is_gfn_in_memslot(slot, gfn))
|
||||
return slot;
|
||||
else
|
||||
return NULL;
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@ -49,11 +49,11 @@
|
||||
# define buildid .local
|
||||
|
||||
%define specversion 4.18.0
|
||||
%define pkgrelease 553.139.3.el8_10
|
||||
%define pkgrelease 553.139.4.el8_10
|
||||
%define tarfile_release 553.139.1.el8_10
|
||||
|
||||
# allow pkg_release to have configurable %%{?dist} tag
|
||||
%define specrelease 553.139.3%{?dist}
|
||||
%define specrelease 553.139.4%{?dist}
|
||||
|
||||
%define pkg_release %{specrelease}%{?buildid}
|
||||
|
||||
@ -554,6 +554,7 @@ Patch2008: 0008-Bring-back-deprecated-pci-ids-to-be2iscsi-driver.patch
|
||||
|
||||
# AlmaLinux ahead-of-RHEL security fixes
|
||||
Patch1100: 1100-kvm-x86-fix-shadow-paging-use-after-free.patch
|
||||
Patch1101: 1101-kvm-x86-mmu-ensure-hugepage-is-in-by-slot.patch
|
||||
|
||||
# END OF PATCH DEFINITIONS
|
||||
|
||||
@ -1134,6 +1135,7 @@ ApplyPatch 0008-Bring-back-deprecated-pci-ids-to-be2iscsi-driver.patch
|
||||
|
||||
# AlmaLinux ahead-of-RHEL security fixes
|
||||
ApplyPatch 1100-kvm-x86-fix-shadow-paging-use-after-free.patch
|
||||
ApplyPatch 1101-kvm-x86-mmu-ensure-hugepage-is-in-by-slot.patch
|
||||
|
||||
# END OF PATCH APPLICATIONS
|
||||
|
||||
@ -2736,6 +2738,10 @@ fi
|
||||
#
|
||||
#
|
||||
%changelog
|
||||
* Thu Jul 02 2026 Andrei Lukoshko <alukoshko@almalinux.org> - 4.18.0-553.139.4
|
||||
- Ensure hugepage is in by slot before checking max mapping level in KVM
|
||||
hugepage recovery, upstream ef057cbf825e (1101)
|
||||
|
||||
* Thu Jul 02 2026 Andrei Lukoshko <alukoshko@almalinux.org> - 4.18.0-553.139.3
|
||||
- Replace CVE-2026-46113 backport patch series with a single combined
|
||||
adaptation of upstream 0cb2af2ea66a and 81ccda30b4e8 (1100)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user