From: Greg Kroah-Hartman Date: Sat, 25 Jul 2026 06:54:04 +0000 (+0200) Subject: 6.1-stable patches X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=e276c5875eb81ae9647d5e77ac356ba57ac52437;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.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 --- diff --git a/queue-6.1/kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch b/queue-6.1/kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch new file mode 100644 index 0000000000..348671473f --- /dev/null +++ b/queue-6.1/kvm-nvmx-hide-shadow-vmcs-right-after-vmclear.patch @@ -0,0 +1,54 @@ +From 622ebfac01ba4f9c0060cebd41257fe46fc4a0b3 Mon Sep 17 00:00:00 2001 +From: Hyunwoo Kim +Date: Fri, 17 Jul 2026 12:30:11 +0200 +Subject: KVM: nVMX: Hide shadow VMCS right after VMCLEAR + +From: Hyunwoo Kim + +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 +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -287,6 +287,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); +@@ -304,9 +305,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.1/kvm-x86-mmu-fix-use-after-free-on-vendor-module-reload.patch b/queue-6.1/kvm-x86-mmu-fix-use-after-free-on-vendor-module-reload.patch new file mode 100644 index 0000000000..c085985fb3 --- /dev/null +++ b/queue-6.1/kvm-x86-mmu-fix-use-after-free-on-vendor-module-reload.patch @@ -0,0 +1,76 @@ +From 52f2f7c30126037975389aa04d24c506a5177c35 Mon Sep 17 00:00:00 2001 +From: Phil Rosenthal +Date: Sat, 18 Jul 2026 12:50:23 -0400 +Subject: KVM: x86/mmu: Fix use-after-free on vendor module reload + +From: Phil Rosenthal + +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 +Message-ID: <20260718-kvm-mmu-cache-uaf-v3-1-e103b93c74e1@phil.gs> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -6643,7 +6643,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 int get_nx_huge_pages(char *buffer, const struct kernel_param *kp) diff --git a/queue-6.1/kvm-x86-only-reset-tsc-deadline-timer-in-apic_timer_expired-on-kvm_run.patch b/queue-6.1/kvm-x86-only-reset-tsc-deadline-timer-in-apic_timer_expired-on-kvm_run.patch new file mode 100644 index 0000000000..bd898ea0a9 --- /dev/null +++ b/queue-6.1/kvm-x86-only-reset-tsc-deadline-timer-in-apic_timer_expired-on-kvm_run.patch @@ -0,0 +1,64 @@ +From e800decd9c0ac4349bcd8f8f9b29fd21fe93165e Mon Sep 17 00:00:00 2001 +From: Venkatesh Srinivas +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 + +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 +Debugged-by: Sean Christopherson +Debugged-by: Jim Mattson +Debugged-by: James Houghton +Signed-off-by: Venkatesh Srinivas +Message-ID: <20260715234234.15382-2-venkateshs@chromium.org> +Reviewed-by: James Houghton +Reviewed-by: Chao Gao +Cc: stable@vger.kernel.org +Fixes: ae95f566b3d2 ("KVM: X86: TSCDEADLINE MSR emulation fastpath", 2020-05-15) +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -1745,7 +1745,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; diff --git a/queue-6.1/series b/queue-6.1/series index 40a31337ee..46ac8f8c14 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -4,3 +4,6 @@ perf-x86-amd-brs-fix-kernel-address-leakage.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-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