Skip to content

Commit

Permalink
nSVM: Check addresses of MSR and IO permission maps
Browse files Browse the repository at this point in the history
According to section "Canonicalization and Consistency Checks" in APM vol 2,
the following guest state is illegal:

    "The MSR or IOIO intercept tables extend to a physical address that
     is greater than or equal to the maximum supported physical address."

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
Message-Id: <20210412215611.110095-5-krish.sadhukhan@oracle.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
Krish Sadhukhan authored and Paolo Bonzini committed Apr 21, 2021
1 parent 47903dc commit ee695f2
Showing 1 changed file with 22 additions and 3 deletions.
25 changes: 22 additions & 3 deletions arch/x86/kvm/svm/nested.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,19 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
return true;
}

static bool nested_vmcb_check_controls(struct vmcb_control_area *control)
/*
* Bits 11:0 of bitmap address are ignored by hardware
*/
static bool nested_svm_check_bitmap_pa(struct kvm_vcpu *vcpu, u64 pa, u32 size)
{
u64 addr = PAGE_ALIGN(pa);

return kvm_vcpu_is_legal_gpa(vcpu, addr) &&
kvm_vcpu_is_legal_gpa(vcpu, addr + size - 1);
}

static bool nested_vmcb_check_controls(struct kvm_vcpu *vcpu,
struct vmcb_control_area *control)
{
if (CC(!vmcb_is_intercept(control, INTERCEPT_VMRUN)))
return false;
Expand All @@ -226,6 +238,13 @@ static bool nested_vmcb_check_controls(struct vmcb_control_area *control)
if (CC((control->nested_ctl & SVM_NESTED_CTL_NP_ENABLE) && !npt_enabled))
return false;

if (CC(!nested_svm_check_bitmap_pa(vcpu, control->msrpm_base_pa,
MSRPM_SIZE)))
return false;
if (CC(!nested_svm_check_bitmap_pa(vcpu, control->iopm_base_pa,
IOPM_SIZE)))
return false;

return true;
}

Expand Down Expand Up @@ -604,7 +623,7 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu)
nested_load_control_from_vmcb12(svm, &vmcb12->control);

if (!nested_vmcb_valid_sregs(vcpu, &vmcb12->save) ||
!nested_vmcb_check_controls(&svm->nested.ctl)) {
!nested_vmcb_check_controls(vcpu, &svm->nested.ctl)) {
vmcb12->control.exit_code = SVM_EXIT_ERR;
vmcb12->control.exit_code_hi = 0;
vmcb12->control.exit_info_1 = 0;
Expand Down Expand Up @@ -1252,7 +1271,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
goto out_free;

ret = -EINVAL;
if (!nested_vmcb_check_controls(ctl))
if (!nested_vmcb_check_controls(vcpu, ctl))
goto out_free;

/*
Expand Down

0 comments on commit ee695f2

Please sign in to comment.