| From 37f6a4e237303549c8676dfe1fd1991ceab512eb Mon Sep 17 00:00:00 2001 |
| From: Marcelo Tosatti <mtosatti@redhat.com> |
| Date: Fri, 3 Jan 2014 17:09:32 -0200 |
| Subject: KVM: x86: handle invalid root_hpa everywhere |
| |
| From: Marcelo Tosatti <mtosatti@redhat.com> |
| |
| commit 37f6a4e237303549c8676dfe1fd1991ceab512eb upstream. |
| |
| Rom Freiman <rom@stratoscale.com> notes other code paths vulnerable to |
| bug fixed by 989c6b34f6a9480e397b. |
| |
| Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> |
| Cc: Josh Boyer <jwboyer@fedoraproject.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/x86/kvm/mmu.c | 9 +++++++++ |
| arch/x86/kvm/paging_tmpl.h | 8 ++++++++ |
| 2 files changed, 17 insertions(+) |
| |
| --- a/arch/x86/kvm/mmu.c |
| +++ b/arch/x86/kvm/mmu.c |
| @@ -2832,6 +2832,9 @@ static bool fast_page_fault(struct kvm_v |
| bool ret = false; |
| u64 spte = 0ull; |
| |
| + if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) |
| + return false; |
| + |
| if (!page_fault_can_be_fast(error_code)) |
| return false; |
| |
| @@ -3227,6 +3230,9 @@ static u64 walk_shadow_page_get_mmio_spt |
| struct kvm_shadow_walk_iterator iterator; |
| u64 spte = 0ull; |
| |
| + if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) |
| + return spte; |
| + |
| walk_shadow_page_lockless_begin(vcpu); |
| for_each_shadow_entry_lockless(vcpu, addr, iterator, spte) |
| if (!is_shadow_present_pte(spte)) |
| @@ -4513,6 +4519,9 @@ int kvm_mmu_get_spte_hierarchy(struct kv |
| u64 spte; |
| int nr_sptes = 0; |
| |
| + if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) |
| + return nr_sptes; |
| + |
| walk_shadow_page_lockless_begin(vcpu); |
| for_each_shadow_entry_lockless(vcpu, addr, iterator, spte) { |
| sptes[iterator.level-1] = spte; |
| --- a/arch/x86/kvm/paging_tmpl.h |
| +++ b/arch/x86/kvm/paging_tmpl.h |
| @@ -569,6 +569,9 @@ static int FNAME(fetch)(struct kvm_vcpu |
| if (FNAME(gpte_changed)(vcpu, gw, top_level)) |
| goto out_gpte_changed; |
| |
| + if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) |
| + goto out_gpte_changed; |
| + |
| for (shadow_walk_init(&it, vcpu, addr); |
| shadow_walk_okay(&it) && it.level > gw->level; |
| shadow_walk_next(&it)) { |
| @@ -820,6 +823,11 @@ static void FNAME(invlpg)(struct kvm_vcp |
| */ |
| mmu_topup_memory_caches(vcpu); |
| |
| + if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) { |
| + WARN_ON(1); |
| + return; |
| + } |
| + |
| spin_lock(&vcpu->kvm->mmu_lock); |
| for_each_shadow_entry(vcpu, gva, iterator) { |
| level = iterator.level; |