forked from Minki/linux
KVM: MMU: fix writable sync sp mapping
While we sync many unsync sp at one time(in mmu_sync_children()), we may mapping the spte writable, it's dangerous, if one unsync sp's mapping gfn is another unsync page's gfn. For example: SP1.pte[0] = P SP2.gfn's pfn = P [SP1.pte[0] = SP2.gfn's pfn] First, we write protected SP1 and SP2, but SP1 and SP2 are still the unsync sp. Then, sync SP1 first, it will detect SP1.pte[0].gfn only has one unsync-sp, that is SP2, so it will mapping it writable, but we plan to sync SP2 soon, at this point, the SP2->unsync is not reliable since later we sync SP2 but SP2->gfn is already writable. So the final result is: SP2 is the sync page but SP2.gfn is writable. This bug will corrupt guest's page table, fixed by mark read-only mapping if the mapped gfn has shadow pages. Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
parent
f5f48ee15c
commit
36a2e6774b
@ -1810,11 +1810,14 @@ static int mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn,
|
||||
bool need_unsync = false;
|
||||
|
||||
for_each_gfn_indirect_valid_sp(vcpu->kvm, s, gfn, node) {
|
||||
if (!can_unsync)
|
||||
return 1;
|
||||
|
||||
if (s->role.level != PT_PAGE_TABLE_LEVEL)
|
||||
return 1;
|
||||
|
||||
if (!need_unsync && !s->unsync) {
|
||||
if (!can_unsync || !oos_shadow)
|
||||
if (!oos_shadow)
|
||||
return 1;
|
||||
need_unsync = true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user