From: Greg Kroah-Hartman Date: Mon, 6 Mar 2023 17:16:36 +0000 (+0100) Subject: 6.2-stable patches X-Git-Tag: v6.2.3~80 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c7e5b282c9dd96aed913dd11481ee938f961b5fb;p=thirdparty%2Fkernel%2Fstable-queue.git 6.2-stable patches added patches: kvm-destroy-target-device-if-coalesced-mmio-unregistration-fails.patch kvm-register-dev-kvm-as-the-_very_-last-thing-during-initialization.patch kvm-vmx-fix-crash-due-to-uninitialized-current_vmcs.patch --- diff --git a/queue-6.2/kvm-destroy-target-device-if-coalesced-mmio-unregistration-fails.patch b/queue-6.2/kvm-destroy-target-device-if-coalesced-mmio-unregistration-fails.patch new file mode 100644 index 00000000000..a08cc3f625c --- /dev/null +++ b/queue-6.2/kvm-destroy-target-device-if-coalesced-mmio-unregistration-fails.patch @@ -0,0 +1,74 @@ +From b1cb1fac22abf102ffeb29dd3eeca208a3869d54 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Mon, 19 Dec 2022 17:19:24 +0000 +Subject: KVM: Destroy target device if coalesced MMIO unregistration fails +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Sean Christopherson + +commit b1cb1fac22abf102ffeb29dd3eeca208a3869d54 upstream. + +Destroy and free the target coalesced MMIO device if unregistering said +device fails. As clearly noted in the code, kvm_io_bus_unregister_dev() +does not destroy the target device. + + BUG: memory leak + unreferenced object 0xffff888112a54880 (size 64): + comm "syz-executor.2", pid 5258, jiffies 4297861402 (age 14.129s) + hex dump (first 32 bytes): + 38 c7 67 15 00 c9 ff ff 38 c7 67 15 00 c9 ff ff 8.g.....8.g..... + e0 c7 e1 83 ff ff ff ff 00 30 67 15 00 c9 ff ff .........0g..... + backtrace: + [<0000000006995a8a>] kmalloc include/linux/slab.h:556 [inline] + [<0000000006995a8a>] kzalloc include/linux/slab.h:690 [inline] + [<0000000006995a8a>] kvm_vm_ioctl_register_coalesced_mmio+0x8e/0x3d0 arch/x86/kvm/../../../virt/kvm/coalesced_mmio.c:150 + [<00000000022550c2>] kvm_vm_ioctl+0x47d/0x1600 arch/x86/kvm/../../../virt/kvm/kvm_main.c:3323 + [<000000008a75102f>] vfs_ioctl fs/ioctl.c:46 [inline] + [<000000008a75102f>] file_ioctl fs/ioctl.c:509 [inline] + [<000000008a75102f>] do_vfs_ioctl+0xbab/0x1160 fs/ioctl.c:696 + [<0000000080e3f669>] ksys_ioctl+0x76/0xa0 fs/ioctl.c:713 + [<0000000059ef4888>] __do_sys_ioctl fs/ioctl.c:720 [inline] + [<0000000059ef4888>] __se_sys_ioctl fs/ioctl.c:718 [inline] + [<0000000059ef4888>] __x64_sys_ioctl+0x6f/0xb0 fs/ioctl.c:718 + [<000000006444fa05>] do_syscall_64+0x9f/0x4e0 arch/x86/entry/common.c:290 + [<000000009a4ed50b>] entry_SYSCALL_64_after_hwframe+0x49/0xbe + + BUG: leak checking failed + +Fixes: 5d3c4c79384a ("KVM: Stop looking for coalesced MMIO zones if the bus is destroyed") +Cc: stable@vger.kernel.org +Reported-by: 柳菁峰 +Reported-by: Michal Luczaj +Link: https://lore.kernel.org/r/20221219171924.67989-1-seanjc@google.com +Link: https://lore.kernel.org/all/20230118220003.1239032-1-mhal@rbox.co +Signed-off-by: Sean Christopherson +Signed-off-by: Greg Kroah-Hartman +--- + virt/kvm/coalesced_mmio.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/virt/kvm/coalesced_mmio.c ++++ b/virt/kvm/coalesced_mmio.c +@@ -187,15 +187,17 @@ int kvm_vm_ioctl_unregister_coalesced_mm + r = kvm_io_bus_unregister_dev(kvm, + zone->pio ? KVM_PIO_BUS : KVM_MMIO_BUS, &dev->dev); + ++ kvm_iodevice_destructor(&dev->dev); ++ + /* + * On failure, unregister destroys all devices on the + * bus _except_ the target device, i.e. coalesced_zones +- * has been modified. No need to restart the walk as +- * there aren't any zones left. ++ * has been modified. Bail after destroying the target ++ * device, there's no need to restart the walk as there ++ * aren't any zones left. + */ + if (r) + break; +- kvm_iodevice_destructor(&dev->dev); + } + } + diff --git a/queue-6.2/kvm-register-dev-kvm-as-the-_very_-last-thing-during-initialization.patch b/queue-6.2/kvm-register-dev-kvm-as-the-_very_-last-thing-during-initialization.patch new file mode 100644 index 00000000000..bbc3e04d4c7 --- /dev/null +++ b/queue-6.2/kvm-register-dev-kvm-as-the-_very_-last-thing-during-initialization.patch @@ -0,0 +1,83 @@ +From 2b01281273738bf2d6551da48d65db2df3f28998 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Wed, 30 Nov 2022 23:08:45 +0000 +Subject: KVM: Register /dev/kvm as the _very_ last thing during initialization + +From: Sean Christopherson + +commit 2b01281273738bf2d6551da48d65db2df3f28998 upstream. + +Register /dev/kvm, i.e. expose KVM to userspace, only after all other +setup has completed. Once /dev/kvm is exposed, userspace can start +invoking KVM ioctls, creating VMs, etc... If userspace creates a VM +before KVM is done with its configuration, bad things may happen, e.g. +KVM will fail to properly migrate vCPU state if a VM is created before +KVM has registered preemption notifiers. + +Cc: stable@vger.kernel.org +Signed-off-by: Sean Christopherson +Message-Id: <20221130230934.1014142-2-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + virt/kvm/kvm_main.c | 31 ++++++++++++++++++++++--------- + 1 file changed, 22 insertions(+), 9 deletions(-) + +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -5995,12 +5995,6 @@ int kvm_init(void *opaque, unsigned vcpu + + kvm_chardev_ops.owner = module; + +- r = misc_register(&kvm_dev); +- if (r) { +- pr_err("kvm: misc device register failed\n"); +- goto out_unreg; +- } +- + register_syscore_ops(&kvm_syscore_ops); + + kvm_preempt_ops.sched_in = kvm_sched_in; +@@ -6009,11 +6003,24 @@ int kvm_init(void *opaque, unsigned vcpu + kvm_init_debug(); + + r = kvm_vfio_ops_init(); +- WARN_ON(r); ++ if (WARN_ON_ONCE(r)) ++ goto err_vfio; ++ ++ /* ++ * Registration _must_ be the very last thing done, as this exposes ++ * /dev/kvm to userspace, i.e. all infrastructure must be setup! ++ */ ++ r = misc_register(&kvm_dev); ++ if (r) { ++ pr_err("kvm: misc device register failed\n"); ++ goto err_register; ++ } + + return 0; + +-out_unreg: ++err_register: ++ kvm_vfio_ops_exit(); ++err_vfio: + kvm_async_pf_deinit(); + out_free_4: + for_each_possible_cpu(cpu) +@@ -6039,8 +6046,14 @@ void kvm_exit(void) + { + int cpu; + +- debugfs_remove_recursive(kvm_debugfs_dir); ++ /* ++ * Note, unregistering /dev/kvm doesn't strictly need to come first, ++ * fops_get(), a.k.a. try_module_get(), prevents acquiring references ++ * to KVM while the module is being stopped. ++ */ + misc_deregister(&kvm_dev); ++ ++ debugfs_remove_recursive(kvm_debugfs_dir); + for_each_possible_cpu(cpu) + free_cpumask_var(per_cpu(cpu_kick_mask, cpu)); + kmem_cache_destroy(kvm_vcpu_cache); diff --git a/queue-6.2/kvm-vmx-fix-crash-due-to-uninitialized-current_vmcs.patch b/queue-6.2/kvm-vmx-fix-crash-due-to-uninitialized-current_vmcs.patch new file mode 100644 index 00000000000..b4d06e3d009 --- /dev/null +++ b/queue-6.2/kvm-vmx-fix-crash-due-to-uninitialized-current_vmcs.patch @@ -0,0 +1,99 @@ +From 93827a0a36396f2fd6368a54a020f420c8916e9b Mon Sep 17 00:00:00 2001 +From: Alexandru Matei +Date: Tue, 24 Jan 2023 00:12:08 +0200 +Subject: KVM: VMX: Fix crash due to uninitialized current_vmcs + +From: Alexandru Matei + +commit 93827a0a36396f2fd6368a54a020f420c8916e9b upstream. + +KVM enables 'Enlightened VMCS' and 'Enlightened MSR Bitmap' when running as +a nested hypervisor on top of Hyper-V. When MSR bitmap is updated, +evmcs_touch_msr_bitmap function uses current_vmcs per-cpu variable to mark +that the msr bitmap was changed. + +vmx_vcpu_create() modifies the msr bitmap via vmx_disable_intercept_for_msr +-> vmx_msr_bitmap_l01_changed which in the end calls this function. The +function checks for current_vmcs if it is null but the check is +insufficient because current_vmcs is not initialized. Because of this, the +code might incorrectly write to the structure pointed by current_vmcs value +left by another task. Preemption is not disabled, the current task can be +preempted and moved to another CPU while current_vmcs is accessed multiple +times from evmcs_touch_msr_bitmap() which leads to crash. + +The manipulation of MSR bitmaps by callers happens only for vmcs01 so the +solution is to use vmx->vmcs01.vmcs instead of current_vmcs. + + BUG: kernel NULL pointer dereference, address: 0000000000000338 + PGD 4e1775067 P4D 0 + Oops: 0002 [#1] PREEMPT SMP NOPTI + ... + RIP: 0010:vmx_msr_bitmap_l01_changed+0x39/0x50 [kvm_intel] + ... + Call Trace: + vmx_disable_intercept_for_msr+0x36/0x260 [kvm_intel] + vmx_vcpu_create+0xe6/0x540 [kvm_intel] + kvm_arch_vcpu_create+0x1d1/0x2e0 [kvm] + kvm_vm_ioctl_create_vcpu+0x178/0x430 [kvm] + kvm_vm_ioctl+0x53f/0x790 [kvm] + __x64_sys_ioctl+0x8a/0xc0 + do_syscall_64+0x5c/0x90 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Fixes: ceef7d10dfb6 ("KVM: x86: VMX: hyper-v: Enlightened MSR-Bitmap support") +Cc: stable@vger.kernel.org +Suggested-by: Sean Christopherson +Signed-off-by: Alexandru Matei +Link: https://lore.kernel.org/r/20230123221208.4964-1-alexandru.matei@uipath.com +Signed-off-by: Sean Christopherson +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/vmx/hyperv.h | 11 ----------- + arch/x86/kvm/vmx/vmx.c | 9 +++++++-- + 2 files changed, 7 insertions(+), 13 deletions(-) + +--- a/arch/x86/kvm/vmx/hyperv.h ++++ b/arch/x86/kvm/vmx/hyperv.h +@@ -190,16 +190,6 @@ static inline u16 evmcs_read16(unsigned + return *(u16 *)((char *)current_evmcs + offset); + } + +-static inline void evmcs_touch_msr_bitmap(void) +-{ +- if (unlikely(!current_evmcs)) +- return; +- +- if (current_evmcs->hv_enlightenments_control.msr_bitmap) +- current_evmcs->hv_clean_fields &= +- ~HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP; +-} +- + static inline void evmcs_load(u64 phys_addr) + { + struct hv_vp_assist_page *vp_ap = +@@ -219,7 +209,6 @@ static inline u64 evmcs_read64(unsigned + static inline u32 evmcs_read32(unsigned long field) { return 0; } + static inline u16 evmcs_read16(unsigned long field) { return 0; } + static inline void evmcs_load(u64 phys_addr) {} +-static inline void evmcs_touch_msr_bitmap(void) {} + #endif /* IS_ENABLED(CONFIG_HYPERV) */ + + #define EVMPTR_INVALID (-1ULL) +--- a/arch/x86/kvm/vmx/vmx.c ++++ b/arch/x86/kvm/vmx/vmx.c +@@ -3865,8 +3865,13 @@ static void vmx_msr_bitmap_l01_changed(s + * 'Enlightened MSR Bitmap' feature L0 needs to know that MSR + * bitmap has changed. + */ +- if (static_branch_unlikely(&enable_evmcs)) +- evmcs_touch_msr_bitmap(); ++ if (IS_ENABLED(CONFIG_HYPERV) && static_branch_unlikely(&enable_evmcs)) { ++ struct hv_enlightened_vmcs *evmcs = (void *)vmx->vmcs01.vmcs; ++ ++ if (evmcs->hv_enlightenments_control.msr_bitmap) ++ evmcs->hv_clean_fields &= ++ ~HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP; ++ } + + vmx->nested.force_msr_bitmap_recalc = true; + } diff --git a/queue-6.2/series b/queue-6.2/series index e15545fc322..cfae825aec2 100644 --- a/queue-6.2/series +++ b/queue-6.2/series @@ -819,3 +819,6 @@ udf-preserve-link-count-of-system-files.patch udf-detect-system-inodes-linked-into-directory-hierarchy.patch udf-fix-file-corruption-when-appending-just-after-end-of-preallocated-extent.patch md-don-t-update-recovery_cp-when-curr_resync-is-active.patch +kvm-destroy-target-device-if-coalesced-mmio-unregistration-fails.patch +kvm-vmx-fix-crash-due-to-uninitialized-current_vmcs.patch +kvm-register-dev-kvm-as-the-_very_-last-thing-during-initialization.patch