linux/arch
Vitaly Kuznetsov 7a35e515a7 KVM: VMX: Properly handle kvm_read/write_guest_virt*() result
Syzbot reports the following issue:

WARNING: CPU: 0 PID: 6819 at arch/x86/kvm/x86.c:618
 kvm_inject_emulated_page_fault+0x210/0x290 arch/x86/kvm/x86.c:618
...
Call Trace:
...
RIP: 0010:kvm_inject_emulated_page_fault+0x210/0x290 arch/x86/kvm/x86.c:618
...
 nested_vmx_get_vmptr+0x1f9/0x2a0 arch/x86/kvm/vmx/nested.c:4638
 handle_vmon arch/x86/kvm/vmx/nested.c:4767 [inline]
 handle_vmon+0x168/0x3a0 arch/x86/kvm/vmx/nested.c:4728
 vmx_handle_exit+0x29c/0x1260 arch/x86/kvm/vmx/vmx.c:6067

'exception' we're trying to inject with kvm_inject_emulated_page_fault()
comes from:

  nested_vmx_get_vmptr()
   kvm_read_guest_virt()
     kvm_read_guest_virt_helper()
       vcpu->arch.walk_mmu->gva_to_gpa()

but it is only set when GVA to GPA conversion fails. In case it doesn't but
we still fail kvm_vcpu_read_guest_page(), X86EMUL_IO_NEEDED is returned and
nested_vmx_get_vmptr() calls kvm_inject_emulated_page_fault() with zeroed
'exception'. This happen when the argument is MMIO.

Paolo also noticed that nested_vmx_get_vmptr() is not the only place in
KVM code where kvm_read/write_guest_virt*() return result is mishandled.
VMX instructions along with INVPCID have the same issue. This was already
noticed before, e.g. see commit 541ab2aeb2 ("KVM: x86: work around
leak of uninitialized stack contents") but was never fully fixed.

KVM could've handled the request correctly by going to userspace and
performing I/O but there doesn't seem to be a good need for such requests
in the first place.

Introduce vmx_handle_memory_failure() as an interim solution.

Note, nested_vmx_get_vmptr() now has three possible outcomes: OK, PF,
KVM_EXIT_INTERNAL_ERROR and callers need to know if userspace exit is
needed (for KVM_EXIT_INTERNAL_ERROR) in case of failure. We don't seem
to have a good enum describing this tristate, just add "int *ret" to
nested_vmx_get_vmptr() interface to pass the information.

Reported-by: syzbot+2a7156e11dc199bdbd8a@syzkaller.appspotmail.com
Suggested-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Message-Id: <20200605115906.532682-1-vkuznets@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2020-06-08 07:59:08 -04:00
..
alpha alpha: simplify detection of memory zone boundaries 2020-06-03 20:09:43 -07:00
arc mm/thp: rename pmd_mknotpresent() as pmd_mkinvalid() 2020-06-03 20:09:49 -07:00
arm media updates for v5.8-rc1 2020-06-03 20:59:38 -07:00
arm64 KVM: let kvm_destroy_vm_debugfs clean up vCPU debugfs directories 2020-06-04 11:00:54 -04:00
c6x mm: free_area_init: use maximal zone PFNs rather than zone sizes 2020-06-03 20:09:43 -07:00
csky csky: simplify detection of memory zone boundaries 2020-06-03 20:09:43 -07:00
h8300 mm: free_area_init: use maximal zone PFNs rather than zone sizes 2020-06-03 20:09:43 -07:00
hexagon mm: free_area_init: use maximal zone PFNs rather than zone sizes 2020-06-03 20:09:43 -07:00
ia64 Merge branch 'akpm' (patches from Andrew) 2020-06-03 20:24:15 -07:00
m68k m68k: mm: simplify detection of memory zone boundaries 2020-06-03 20:09:43 -07:00
microblaze mm: use free_area_init() instead of free_area_init_nodes() 2020-06-03 20:09:43 -07:00
mips KVM: MIPS: Enable KVM support for Loongson-3 2020-06-04 13:51:53 -04:00
nds32 mm: free_area_init: use maximal zone PFNs rather than zone sizes 2020-06-03 20:09:43 -07:00
nios2 mm: free_area_init: use maximal zone PFNs rather than zone sizes 2020-06-03 20:09:43 -07:00
openrisc mm: free_area_init: use maximal zone PFNs rather than zone sizes 2020-06-03 20:09:43 -07:00
parisc Merge branch 'akpm' (patches from Andrew) 2020-06-03 20:24:15 -07:00
powerpc PPC KVM update for 5.8 2020-06-04 14:58:03 -04:00
riscv Merge branch 'akpm' (patches from Andrew) 2020-06-03 20:24:15 -07:00
s390 Merge branch 'akpm' (patches from Andrew) 2020-06-03 20:24:15 -07:00
sh mm/hugetlb: define a generic fallback for arch_clear_hugepage_flags() 2020-06-03 20:09:46 -07:00
sparc sparc32: register memory occupied by kernel as memblock.memory 2020-06-03 20:09:49 -07:00
um mm: free_area_init: use maximal zone PFNs rather than zone sizes 2020-06-03 20:09:43 -07:00
unicore32 unicore32: simplify detection of memory zone boundaries 2020-06-03 20:09:43 -07:00
x86 KVM: VMX: Properly handle kvm_read/write_guest_virt*() result 2020-06-08 07:59:08 -04:00
xtensa Merge branch 'akpm' (patches from Andrew) 2020-06-03 20:24:15 -07:00
.gitignore
Kconfig scs: Remove references to asm/scs.h from core code 2020-05-18 17:47:45 +01:00