Skip to content

Commit 59e9777

Browse files
committed
KVM: VMX: Fix crash due to uninitialized current_vmcs
jira LE-1907 Rebuild_History Non-Buildable kernel-5.14.0-284.30.1.el9_2 commit-author Alexandru Matei <[email protected]> commit 93827a0 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: ceef7d1 ("KVM: x86: VMX: hyper-v: Enlightened MSR-Bitmap support") Cc: [email protected] Suggested-by: Sean Christopherson <[email protected]> Signed-off-by: Alexandru Matei <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sean Christopherson <[email protected]> (cherry picked from commit 93827a0) Signed-off-by: Jonathan Maple <[email protected]>
1 parent 41af8eb commit 59e9777

File tree

2 files changed

+7
-13
lines changed

2 files changed

+7
-13
lines changed

arch/x86/kvm/vmx/evmcs.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -191,16 +191,6 @@ static inline u16 evmcs_read16(unsigned long field)
191191
return *(u16 *)((char *)current_evmcs + offset);
192192
}
193193

194-
static inline void evmcs_touch_msr_bitmap(void)
195-
{
196-
if (unlikely(!current_evmcs))
197-
return;
198-
199-
if (current_evmcs->hv_enlightenments_control.msr_bitmap)
200-
current_evmcs->hv_clean_fields &=
201-
~HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP;
202-
}
203-
204194
static inline void evmcs_load(u64 phys_addr)
205195
{
206196
struct hv_vp_assist_page *vp_ap =
@@ -221,7 +211,6 @@ static inline u64 evmcs_read64(unsigned long field) { return 0; }
221211
static inline u32 evmcs_read32(unsigned long field) { return 0; }
222212
static inline u16 evmcs_read16(unsigned long field) { return 0; }
223213
static inline void evmcs_load(u64 phys_addr) {}
224-
static inline void evmcs_touch_msr_bitmap(void) {}
225214
#endif /* IS_ENABLED(CONFIG_HYPERV) */
226215

227216
#define EVMPTR_INVALID (-1ULL)

arch/x86/kvm/vmx/vmx.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3886,8 +3886,13 @@ static void vmx_msr_bitmap_l01_changed(struct vcpu_vmx *vmx)
38863886
* 'Enlightened MSR Bitmap' feature L0 needs to know that MSR
38873887
* bitmap has changed.
38883888
*/
3889-
if (static_branch_unlikely(&enable_evmcs))
3890-
evmcs_touch_msr_bitmap();
3889+
if (IS_ENABLED(CONFIG_HYPERV) && static_branch_unlikely(&enable_evmcs)) {
3890+
struct hv_enlightened_vmcs *evmcs = (void *)vmx->vmcs01.vmcs;
3891+
3892+
if (evmcs->hv_enlightenments_control.msr_bitmap)
3893+
evmcs->hv_clean_fields &=
3894+
~HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP;
3895+
}
38913896

38923897
vmx->nested.force_msr_bitmap_recalc = true;
38933898
}

0 commit comments

Comments
 (0)