kvm: arm/arm64: Fix race in resetting stage2 PGD
commit
6c0d706b563af732adb094c5bf807437e8963e84 upstream.
In kvm_free_stage2_pgd() we check the stage2 PGD before holding
the lock and proceed to take the lock if it is valid. And we unmap
the page tables, followed by releasing the lock. We reset the PGD
only after dropping this lock, which could cause a race condition
where another thread waiting on or even holding the lock, could
potentially see that the PGD is still valid and proceed to perform
a stage2 operation and later encounter a NULL PGD.
[223090.242280] Unable to handle kernel NULL pointer dereference at
virtual address
00000040
[223090.262330] PC is at unmap_stage2_range+0x8c/0x428
[223090.262332] LR is at kvm_unmap_hva_handler+0x2c/0x3c
[223090.262531] Call trace:
[223090.262533] [<
ffff0000080adb78>] unmap_stage2_range+0x8c/0x428
[223090.262535] [<
ffff0000080adf40>] kvm_unmap_hva_handler+0x2c/0x3c
[223090.262537] [<
ffff0000080ace2c>] handle_hva_to_gpa+0xb0/0x104
[223090.262539] [<
ffff0000080af988>] kvm_unmap_hva+0x5c/0xbc
[223090.262543] [<
ffff0000080a2478>]
kvm_mmu_notifier_invalidate_page+0x50/0x8c
[223090.262547] [<
ffff0000082274f8>]
__mmu_notifier_invalidate_page+0x5c/0x84
[223090.262551] [<
ffff00000820b700>] try_to_unmap_one+0x1d0/0x4a0
[223090.262553] [<
ffff00000820c5c8>] rmap_walk+0x1cc/0x2e0
[223090.262555] [<
ffff00000820c90c>] try_to_unmap+0x74/0xa4
[223090.262557] [<
ffff000008230ce4>] migrate_pages+0x31c/0x5ac
[223090.262561] [<
ffff0000081f869c>] compact_zone+0x3fc/0x7ac
[223090.262563] [<
ffff0000081f8ae0>] compact_zone_order+0x94/0xb0
[223090.262564] [<
ffff0000081f91c0>] try_to_compact_pages+0x108/0x290
[223090.262569] [<
ffff0000081d5108>] __alloc_pages_direct_compact+0x70/0x1ac
[223090.262571] [<
ffff0000081d64a0>] __alloc_pages_nodemask+0x434/0x9f4
[223090.262572] [<
ffff0000082256f0>] alloc_pages_vma+0x230/0x254
[223090.262574] [<
ffff000008235e5c>] do_huge_pmd_anonymous_page+0x114/0x538
[223090.262576] [<
ffff000008201bec>] handle_mm_fault+0xd40/0x17a4
[223090.262577] [<
ffff0000081fb324>] __get_user_pages+0x12c/0x36c
[223090.262578] [<
ffff0000081fb804>] get_user_pages_unlocked+0xa4/0x1b8
[223090.262579] [<
ffff0000080a3ce8>] __gfn_to_pfn_memslot+0x280/0x31c
[223090.262580] [<
ffff0000080a3dd0>] gfn_to_pfn_prot+0x4c/0x5c
[223090.262582] [<
ffff0000080af3f8>] kvm_handle_guest_abort+0x240/0x774
[223090.262584] [<
ffff0000080b2bac>] handle_exit+0x11c/0x1ac
[223090.262586] [<
ffff0000080ab99c>] kvm_arch_vcpu_ioctl_run+0x31c/0x648
[223090.262587] [<
ffff0000080a1d78>] kvm_vcpu_ioctl+0x378/0x768
[223090.262590] [<
ffff00000825df5c>] do_vfs_ioctl+0x324/0x5a4
[223090.262591] [<
ffff00000825e26c>] SyS_ioctl+0x90/0xa4
[223090.262595] [<
ffff000008085d84>] el0_svc_naked+0x38/0x3c
This patch moves the stage2 PGD manipulation under the lock.
Reported-by: Alexander Graf <agraf@suse.de>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Reviewed-by: Christoffer Dall <cdall@linaro.org>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Christoffer Dall <cdall@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>