Skip to content

Commit 898a175

Browse files
bonzinigregkh
authored andcommitted
KVM: SVM: check validity of VMCB controls when returning from SMM
commit be5fa87 upstream. The VMCB12 is stored in guest memory and can be mangled while in SMM; it is then reloaded by svm_leave_smm(), but it is not checked again for validity. Move the cached vmcb12 control and save consistency checks out of svm_set_nested_state() and into a helper, and reuse it in svm_leave_smm(). Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 695b491 commit 898a175

3 files changed

Lines changed: 15 additions & 2 deletions

File tree

arch/x86/kvm/svm/nested.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,15 @@ void nested_copy_vmcb_save_to_cache(struct vcpu_svm *svm,
415415
__nested_copy_vmcb_save_to_cache(&svm->nested.save, save);
416416
}
417417

418+
int nested_svm_check_cached_vmcb12(struct kvm_vcpu *vcpu)
419+
{
420+
if (!nested_vmcb_check_save(vcpu) ||
421+
!nested_vmcb_check_controls(vcpu))
422+
return -EINVAL;
423+
424+
return 0;
425+
}
426+
418427
/*
419428
* Synchronize fields that are written by the processor, so that
420429
* they can be copied back into the vmcb12.
@@ -888,8 +897,7 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu)
888897
nested_copy_vmcb_control_to_cache(svm, &vmcb12->control);
889898
nested_copy_vmcb_save_to_cache(svm, &vmcb12->save);
890899

891-
if (!nested_vmcb_check_save(vcpu) ||
892-
!nested_vmcb_check_controls(vcpu)) {
900+
if (nested_svm_check_cached_vmcb12(vcpu) < 0) {
893901
vmcb12->control.exit_code = SVM_EXIT_ERR;
894902
vmcb12->control.exit_code_hi = -1u;
895903
vmcb12->control.exit_info_1 = 0;

arch/x86/kvm/svm/svm.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4817,6 +4817,10 @@ static int svm_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram)
48174817
vmcb12 = map.hva;
48184818
nested_copy_vmcb_control_to_cache(svm, &vmcb12->control);
48194819
nested_copy_vmcb_save_to_cache(svm, &vmcb12->save);
4820+
4821+
if (nested_svm_check_cached_vmcb12(vcpu) < 0)
4822+
goto unmap_save;
4823+
48204824
ret = enter_svm_guest_mode(vcpu, smram64->svm_guest_vmcb_gpa, vmcb12, false);
48214825

48224826
if (ret)

arch/x86/kvm/svm/svm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,7 @@ static inline int nested_svm_simple_vmexit(struct vcpu_svm *svm, u32 exit_code)
612612

613613
int nested_svm_exit_handled(struct vcpu_svm *svm);
614614
int nested_svm_check_permissions(struct kvm_vcpu *vcpu);
615+
int nested_svm_check_cached_vmcb12(struct kvm_vcpu *vcpu);
615616
int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
616617
bool has_error_code, u32 error_code);
617618
int nested_svm_exit_special(struct vcpu_svm *svm);

0 commit comments

Comments
 (0)