Dear all,I've discovered an issue in the nested VMX implementation, where an unprivileged domain is able to force Xen to dereference a NULL pointer, resulting in a panic.
This is possible when: 1. The malicious domain has nested HVM capabilities. 2. The CPU is running on top of VMX and supports shadow VMCS.To trigger the bug, the domain must first enable VMX operation for itself, execute VMXON and then finally execute VMPTRLD on a guest physical address that is backed by a non-writable p2m mapping. In `nvmx_handle_vmptrld`, after attempting to map the nested VMCS, Xen will check whether or not this mapping is suitable for writing and if not immediately unmap the nested VMCS again and abort the setup of `nvcpu->nv_vvmcx`. However, Xen at this point erroneously continues emulation of the VMPTRLD. In particular, if VMCS shadowing is available, Xen will nonetheless attempt to link up the nested VMCS to its own VMCS in `nvmx_set_vmcs_pointer`. Importantly, Xen here attempts to dereference the presumably mapped nested VMCS (which now is merely a NULL pointer) in order to mark it as a shadow VMCS by applying the `VMCS_RID_TYPE_MASK` to its revision identifier. Following, the page fault handler will panic Xen.
I've attached an XTF reproducer that triggers the bug. To setup such a non-writable p2m mapping for the malicious VMCS, I first setup an appropriate grant table entry. I've tested it on Xen version 4.20.0.
To fix the issue I believe the following patch should be suitable: --- a/xen/arch/x86/hvm/vmx/vvmx.c +++ b/xen/arch/x86/hvm/vmx/vvmx.c@@ -1817,7 +1817,9 @@ static int nvmx_handle_vmptrld(struct cpu_user_regs *regs)
else { hvm_unmap_guest_frame(vvmcx, 1); - vvmcx = NULL; + vmfail(regs, VMX_INSN_VMPTRLD_INVALID_PHYADDR); + + return X86EMUL_OKAY; } } elseThe VMX error AFAICT does not strictly adhere to the Intel SDM, but providing the guest some indication on what went wrong is likely more sensible than silently failing.
Best, Manuel
poc-nested-vmx-shadow-vmcs-vmptrld-nullderef.tar.gz
Description: application/gzip