]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 25 Jul 2026 06:54:42 +0000 (08:54 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 25 Jul 2026 06:54:42 +0000 (08:54 +0200)
added patches:
kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch
kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch
kvm-x86-mmu-fix-use-after-free-on-vendor-module-reload.patch
kvm-x86-only-reset-tsc-deadline-timer-in-apic_timer_expired-on-kvm_run.patch

queue-6.12/kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch [new file with mode: 0644]
queue-6.12/kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch [new file with mode: 0644]
queue-6.12/kvm-x86-mmu-fix-use-after-free-on-vendor-module-reload.patch [new file with mode: 0644]
queue-6.12/kvm-x86-only-reset-tsc-deadline-timer-in-apic_timer_expired-on-kvm_run.patch [new file with mode: 0644]
queue-6.12/series

diff --git a/queue-6.12/kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch b/queue-6.12/kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch
new file mode 100644 (file)
index 0000000..e3310bc
--- /dev/null
@@ -0,0 +1,54 @@
+From 622ebfac01ba4f9c0060cebd41257fe46fc4a0b3 Mon Sep 17 00:00:00 2001
+From: Hyunwoo Kim <imv4bel@gmail.com>
+Date: Fri, 17 Jul 2026 12:30:11 +0200
+Subject: KVM: nVMX: Hide shadow VMCS right after VMCLEAR
+
+From: Hyunwoo Kim <imv4bel@gmail.com>
+
+commit 622ebfac01ba4f9c0060cebd41257fe46fc4a0b3 upstream.
+
+free_nested() frees the shadow VMCS while vmcs01 still points to it. But
+because it is asynchronous with respect to loaded_vmcs_clear(), the vCPU
+might migrate before the pointer is cleared and __loaded_vmcs_clear()
+may then execute VMCLEAR.
+
+The VMCS needs to stay attached until its explicit VMCLEAR completes, but
+then it can be hidden and the page safely freed.
+
+Fixes: 355f4fb1405e ("kvm: nVMX: VMCLEAR an active shadow VMCS after last use")
+Cc: stable@vger.kernel.org
+Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/vmx/nested.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -325,6 +325,7 @@ static void vmx_switch_vmcs(struct kvm_v
+ static void free_nested(struct kvm_vcpu *vcpu)
+ {
+       struct vcpu_vmx *vmx = to_vmx(vcpu);
++      struct vmcs *shadow_vmcs;
+       if (WARN_ON_ONCE(vmx->loaded_vmcs != &vmx->vmcs01))
+               vmx_switch_vmcs(vcpu, &vmx->vmcs01);
+@@ -342,9 +343,15 @@ static void free_nested(struct kvm_vcpu
+       vmx->nested.current_vmptr = INVALID_GPA;
+       if (enable_shadow_vmcs) {
+               vmx_disable_shadow_vmcs(vmx);
+-              vmcs_clear(vmx->vmcs01.shadow_vmcs);
+-              free_vmcs(vmx->vmcs01.shadow_vmcs);
++
++              /*
++               * Keep the pointer visible until after VMCLEAR, so migration
++               * can clear an active shadow VMCS on the old CPU.
++               */
++              shadow_vmcs = vmx->vmcs01.shadow_vmcs;
++              vmcs_clear(shadow_vmcs);
+               vmx->vmcs01.shadow_vmcs = NULL;
++              free_vmcs(shadow_vmcs);
+       }
+       kfree(vmx->nested.cached_vmcs12);
+       vmx->nested.cached_vmcs12 = NULL;
diff --git a/queue-6.12/kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch b/queue-6.12/kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch
new file mode 100644 (file)
index 0000000..26d1373
--- /dev/null
@@ -0,0 +1,86 @@
+From 2abd5287f08319fa35764566b15c6e22cb1068db Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Mon, 13 Jul 2026 08:15:33 -0700
+Subject: KVM: x86: Check for invalid/obsolete root *after* making MMU pages available
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit 2abd5287f08319fa35764566b15c6e22cb1068db upstream.
+
+Check for a "stale" page fault, i.e. for an invalid and/or obsolete root,
+after making MMU pages available for the shadow MMU.  If reclaiming shadow
+pages zaps an in-use root, i.e. marks it invalid, then KVM will attempt to
+map memory into an invalid root.  On its own, populating an invalid root is
+"fine", but because child shadow pages inherit their parent's role, any
+children created during the map/fetch will be created as invalid pages,
+thus violating KVM's invariant that invalid pages are never on the list of
+active MMU pages.
+
+Note, the underlying flaw has existed since KVM first started tracking
+invalid roots in 2008 (commit 2e53d63acba7, "KVM: MMU: ignore zapped root
+pagetables"), but the true badness only came along in 2020 (Linux 5.9)
+with the invariant that invalid shadow pages can't be on the list of
+active pages.
+
+Note #2, inheriting role.invalid when creating child shadow pages is also
+far from ideal; that flaw will be addressed separately.
+
+Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
+Fixes: f95eec9bed76 ("KVM: x86/mmu: Don't put invalid SPs back on the list of active pages")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/mmu/mmu.c         |    9 +++++----
+ arch/x86/kvm/mmu/paging_tmpl.h |   10 ++++++----
+ 2 files changed, 11 insertions(+), 8 deletions(-)
+
+--- a/arch/x86/kvm/mmu/mmu.c
++++ b/arch/x86/kvm/mmu/mmu.c
+@@ -4601,16 +4601,17 @@ static int direct_page_fault(struct kvm_
+       orig_pfn = fault->pfn;
+-      r = RET_PF_RETRY;
+       write_lock(&vcpu->kvm->mmu_lock);
+-      if (is_page_fault_stale(vcpu, fault))
+-              goto out_unlock;
+-
+       r = make_mmu_pages_available(vcpu);
+       if (r)
+               goto out_unlock;
++      if (is_page_fault_stale(vcpu, fault)) {
++              r = RET_PF_RETRY;
++              goto out_unlock;
++      }
++
+       r = direct_map(vcpu, fault);
+ out_unlock:
+--- a/arch/x86/kvm/mmu/paging_tmpl.h
++++ b/arch/x86/kvm/mmu/paging_tmpl.h
+@@ -839,15 +839,17 @@ static int FNAME(page_fault)(struct kvm_
+       orig_pfn = fault->pfn;
+-      r = RET_PF_RETRY;
+       write_lock(&vcpu->kvm->mmu_lock);
+-      if (is_page_fault_stale(vcpu, fault))
+-              goto out_unlock;
+-
+       r = make_mmu_pages_available(vcpu);
+       if (r)
+               goto out_unlock;
++
++      if (is_page_fault_stale(vcpu, fault)) {
++              r = RET_PF_RETRY;
++              goto out_unlock;
++      }
++
+       r = FNAME(fetch)(vcpu, fault, &walker);
+ out_unlock:
diff --git a/queue-6.12/kvm-x86-mmu-fix-use-after-free-on-vendor-module-reload.patch b/queue-6.12/kvm-x86-mmu-fix-use-after-free-on-vendor-module-reload.patch
new file mode 100644 (file)
index 0000000..35f2ad5
--- /dev/null
@@ -0,0 +1,76 @@
+From 52f2f7c30126037975389aa04d24c506a5177c35 Mon Sep 17 00:00:00 2001
+From: Phil Rosenthal <phil@phil.gs>
+Date: Sat, 18 Jul 2026 12:50:23 -0400
+Subject: KVM: x86/mmu: Fix use-after-free on vendor module reload
+
+From: Phil Rosenthal <phil@phil.gs>
+
+commit 52f2f7c30126037975389aa04d24c506a5177c35 upstream.
+
+mmu_destroy_caches() destroys pte_list_desc_cache and
+mmu_page_header_cache, but leaves both pointers unchanged.  The pointers
+live in kvm.ko, and therefore survive when a vendor module is unloaded
+while kvm.ko remains loaded.
+
+If creation of pte_list_desc_cache fails during a subsequent vendor
+module load, its assignment sets pte_list_desc_cache to NULL and the
+error path calls mmu_destroy_caches().  mmu_page_header_cache still
+points to the cache destroyed during the preceding vendor module
+unload.  Passing that stale pointer to kmem_cache_destroy() causes a
+slab use-after-free.
+
+Reproduce the issue on a v7.1.3 kernel with CONFIG_KASAN=y,
+CONFIG_KASAN_GENERIC=y, CONFIG_KVM=m, and CONFIG_KVM_INTEL=m.  A
+one-shot test hook forces pte_list_desc_cache to NULL on the second
+invocation of kvm_mmu_vendor_module_init():
+
+  1. Load kvm.ko and kvm-intel.ko, creating both caches.
+  2. Unload only kvm_intel, leaving kvm.ko loaded.
+  3. Reload kvm_intel and force initialization through the -ENOMEM path.
+
+KASAN reports:
+
+  BUG: KASAN: slab-use-after-free in
+  kvm_mmu_vendor_module_init+0x5b/0x170 [kvm]
+  ...
+  kmem_cache_destroy+0x21/0x1d0
+  kvm_mmu_vendor_module_init+0x5b/0x170 [kvm]
+  ...
+  Allocated by task 16817:
+  __kmem_cache_create_args+0x12c/0x3b0
+  __kmem_cache_create.constprop.0+0xb6/0xf0 [kvm]
+  kvm_mmu_vendor_module_init+0x13b/0x170 [kvm]
+  ...
+  Freed by task 16820:
+  kmem_cache_destroy+0x117/0x1d0
+  kvm_mmu_vendor_module_exit+0x21/0x30 [kvm]
+
+Clear both pointers immediately after destroying their caches so that
+the stored state reflects the caches' lifetime and repeated cleanup is
+safe.
+
+With the fix applied, the same injected vendor module reload fails with
+-ENOMEM as expected and produces no KASAN report.
+
+Fixes: cb498ea2ce1d ("KVM: Portability: Combine kvm_init and kvm_init_x86")
+Cc: stable@vger.kernel.org
+Signed-off-by: Phil Rosenthal <phil@phil.gs>
+Message-ID: <20260718-kvm-mmu-cache-uaf-v3-1-e103b93c74e1@phil.gs>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/mmu/mmu.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/x86/kvm/mmu/mmu.c
++++ b/arch/x86/kvm/mmu/mmu.c
+@@ -7230,7 +7230,9 @@ static struct shrinker *mmu_shrinker;
+ static void mmu_destroy_caches(void)
+ {
+       kmem_cache_destroy(pte_list_desc_cache);
++      pte_list_desc_cache = NULL;
+       kmem_cache_destroy(mmu_page_header_cache);
++      mmu_page_header_cache = NULL;
+ }
+ static void kvm_wake_nx_recovery_thread(struct kvm *kvm)
diff --git a/queue-6.12/kvm-x86-only-reset-tsc-deadline-timer-in-apic_timer_expired-on-kvm_run.patch b/queue-6.12/kvm-x86-only-reset-tsc-deadline-timer-in-apic_timer_expired-on-kvm_run.patch
new file mode 100644 (file)
index 0000000..24336ad
--- /dev/null
@@ -0,0 +1,64 @@
+From e800decd9c0ac4349bcd8f8f9b29fd21fe93165e Mon Sep 17 00:00:00 2001
+From: Venkatesh Srinivas <venkateshs@chromium.org>
+Date: Wed, 15 Jul 2026 23:42:35 +0000
+Subject: KVM: x86: Only reset TSC Deadline Timer in apic_timer_expired on KVM_RUN
+
+From: Venkatesh Srinivas <venkateshs@chromium.org>
+
+commit e800decd9c0ac4349bcd8f8f9b29fd21fe93165e upstream.
+
+On Intel platforms with a VMX preemption timer and APICv, if a VMM
+calls KVM_GET_LAPIC before KVM_GET_MSRS to save the vCPU state, it is
+possible to lose a pending timer interrupt.
+
+If the thread running these ioctls is migrated to another core after
+calling KVM_GET_LAPIC but before KVM_GET_MSRS and the guest is using
+their LAPIC timer in TSC-deadline mode, not only does the save LAPIC
+state not carry the pending interrupt, the TSCDEADLINE MSR will be
+zeroed.
+
+After migration across CPUs, KVM_GET_MSRS calls vcpu_load, posting the
+interrupt and clearing the MSR:
+vcpu_load() ->
+  kvm_arch_vcpu_load() ->
+    kvm_lapic_restart_hv_timer() ->
+      start_hv_timer() ->
+        apic_timer_expired() ->
+          kvm_apic_inject_pending_timer_irqs()
+            . post interrupt into the LAPIC state
+            . clear IA32_TSCDEADLINE
+
+The saved LAPIC state will be missing the pending interrupt and the saved
+MSR will be zero. Oops.
+
+Fix by only posting an interrupt when we're attempting to enter the guest
+(vcpu->wants_to_run == true), not for vcpu_load from other paths.
+
+Assisted-by: gemini:gemini-3.1-pro-preview
+Debugged-by: David Matlack <dmatlack@google.com>
+Debugged-by: Sean Christopherson <seanjc@google.com>
+Debugged-by: Jim Mattson <jmattson@google.com>
+Debugged-by: James Houghton <jthoughton@google.com>
+Signed-off-by: Venkatesh Srinivas <venkateshs@chromium.org>
+Message-ID: <20260715234234.15382-2-venkateshs@chromium.org>
+Reviewed-by: James Houghton <jthoughton@google.com>
+Reviewed-by: Chao Gao <chao.gao@intel.com>
+Cc: stable@vger.kernel.org
+Fixes: ae95f566b3d2 ("KVM: X86: TSCDEADLINE MSR emulation fastpath", 2020-05-15)
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/lapic.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/kvm/lapic.c
++++ b/arch/x86/kvm/lapic.c
+@@ -1923,7 +1923,7 @@ static void apic_timer_expired(struct kv
+       if (apic_lvtt_tscdeadline(apic) || ktimer->hv_timer_in_use)
+               ktimer->expired_tscdeadline = ktimer->tscdeadline;
+-      if (!from_timer_fn && apic->apicv_active) {
++      if (!from_timer_fn && apic->apicv_active && vcpu->wants_to_run) {
+               WARN_ON(kvm_get_running_vcpu() != vcpu);
+               kvm_apic_inject_pending_timer_irqs(apic);
+               return;
index 0e7a6a4e6f8f5ca80d236282889dc3ed257e3787..c22ed8bec4c2cb2fc030093e24c06e9a51adf1e6 100644 (file)
@@ -11,3 +11,7 @@ fs-proc-task_mmu-fix-make_uffd_wp_huge_pte-prot-upda.patch
 seqlock-cure-some-more-scoped_seqlock-optimization-fails.patch
 seqlock-allow-kasan-to-fail-optimizing.patch
 seqlock-allow-ubsan_alignment-to-fail-optimizing.patch
+kvm-x86-check-for-invalid-obsolete-root-after-making-mmu-pages-available.patch
+kvm-x86-only-reset-tsc-deadline-timer-in-apic_timer_expired-on-kvm_run.patch
+kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch
+kvm-x86-mmu-fix-use-after-free-on-vendor-module-reload.patch