KVM: x86/mmu: Check PDPTRs before allocating PAE roots
Check the validity of the PDPTRs before allocating any of the PAE roots, otherwise a bad PDPTR will cause KVM to leak any previously allocated roots. Signed-off-by: Sean Christopherson <seanjc@google.com> Message-Id: <20210305011101.3597423-8-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
committed by
Paolo Bonzini
parent
6e6ec58485
commit
6e0918aec4
+14
-6
@@ -3275,7 +3275,7 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
|
||||
static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_mmu *mmu = vcpu->arch.mmu;
|
||||
u64 pdptr, pm_mask;
|
||||
u64 pdptrs[4], pm_mask;
|
||||
gfn_t root_gfn, root_pgd;
|
||||
hpa_t root;
|
||||
int i;
|
||||
@@ -3286,6 +3286,17 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
|
||||
if (mmu_check_root(vcpu, root_gfn))
|
||||
return 1;
|
||||
|
||||
if (mmu->root_level == PT32E_ROOT_LEVEL) {
|
||||
for (i = 0; i < 4; ++i) {
|
||||
pdptrs[i] = mmu->get_pdptr(vcpu, i);
|
||||
if (!(pdptrs[i] & PT_PRESENT_MASK))
|
||||
continue;
|
||||
|
||||
if (mmu_check_root(vcpu, pdptrs[i] >> PAGE_SHIFT))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Do we shadow a long mode page table? If so we need to
|
||||
* write-protect the guests page table root.
|
||||
@@ -3315,14 +3326,11 @@ static int mmu_alloc_shadow_roots(struct kvm_vcpu *vcpu)
|
||||
MMU_WARN_ON(VALID_PAGE(mmu->pae_root[i]));
|
||||
|
||||
if (mmu->root_level == PT32E_ROOT_LEVEL) {
|
||||
pdptr = mmu->get_pdptr(vcpu, i);
|
||||
if (!(pdptr & PT_PRESENT_MASK)) {
|
||||
if (!(pdptrs[i] & PT_PRESENT_MASK)) {
|
||||
mmu->pae_root[i] = 0;
|
||||
continue;
|
||||
}
|
||||
root_gfn = pdptr >> PAGE_SHIFT;
|
||||
if (mmu_check_root(vcpu, root_gfn))
|
||||
return 1;
|
||||
root_gfn = pdptrs[i] >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
root = mmu_alloc_root(vcpu, root_gfn, i << 30,
|
||||
|
||||
Reference in New Issue
Block a user