Commit ed2d922a authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Jialin Zhang
Browse files

KVM: nVMX: add missing consistency checks for CR0 and CR4

stable inclusion
from stable-v5.10.176
commit c54974ccaff73525462e278602dfe4069877cfaa
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I6U7AN
CVE: CVE-2023-30456

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=c54974ccaff73525462e278602dfe4069877cfaa



--------------------------------

commit 112e6601 upstream.

The effective values of the guest CR0 and CR4 registers may differ from
those included in the VMCS12.  In particular, disabling EPT forces
CR4.PAE=1 and disabling unrestricted guest mode forces CR0.PG=CR0.PE=1.

Therefore, checks on these bits cannot be delegated to the processor
and must be performed by KVM.

Reported-by: default avatarReima ISHII <ishiir@g.ecc.u-tokyo.ac.jp>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarLin Yujun <linyujun809@huawei.com>
Reviewed-by: default avatarZhang Jianhua <chris.zjh@huawei.com>
Reviewed-by: default avatarXiu Jianfeng <xiujianfeng@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parent ab83903a
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -2995,7 +2995,7 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
					struct vmcs12 *vmcs12,
					enum vm_entry_failure_code *entry_failure_code)
{
	bool ia32e;
	bool ia32e = !!(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE);

	*entry_failure_code = ENTRY_FAIL_DEFAULT;

@@ -3021,6 +3021,13 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
					   vmcs12->guest_ia32_perf_global_ctrl)))
		return -EINVAL;

	if (CC((vmcs12->guest_cr0 & (X86_CR0_PG | X86_CR0_PE)) == X86_CR0_PG))
		return -EINVAL;

	if (CC(ia32e && !(vmcs12->guest_cr4 & X86_CR4_PAE)) ||
	    CC(ia32e && !(vmcs12->guest_cr0 & X86_CR0_PG)))
		return -EINVAL;

	/*
	 * If the load IA32_EFER VM-entry control is 1, the following checks
	 * are performed on the field for the IA32_EFER MSR:
@@ -3032,7 +3039,6 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
	 */
	if (to_vmx(vcpu)->nested.nested_run_pending &&
	    (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_EFER)) {
		ia32e = (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) != 0;
		if (CC(!kvm_valid_efer(vcpu, vmcs12->guest_ia32_efer)) ||
		    CC(ia32e != !!(vmcs12->guest_ia32_efer & EFER_LMA)) ||
		    CC(((vmcs12->guest_cr0 & X86_CR0_PG) &&