Re: [PATCH v1 2/4] x86/tdx: Add validation of userspace MMIO instructions
From: Kirill A. Shutemov
Date: Fri Aug 02 2024 - 03:41:31 EST
On Tue, Jul 30, 2024 at 07:35:57PM +0200, Alexey Gladkov (Intel) wrote:
> +static int valid_vaddr(struct ve_info *ve, enum insn_mmio_type mmio, int size,
> + unsigned long vaddr)
> +{
> + phys_addr_t phys_addr;
> + bool writable = false;
> +
> + /* It's not fatal. This can happen due to swap out or page migration. */
> + if (get_phys_addr(vaddr, &phys_addr, &writable) || (ve->gpa != cc_mkdec(phys_addr)))
> + return -EAGAIN;
I think we need big fat comment here why these checks are needed.
We have ve->gpa and it was valid at the time we got ve_info. But after we
get ve_info, we enable interrupts allowing tlb shootdown and therefore
munmap() in parallel thread of the process.
So by the time we've got here ve->gpa might be unmapped from the process,
the device it belongs to removed from system and something else could be
plugged in its place.
That's why we need to re-check if the GPA is still mapped and writable if
we are going to write to it.
> +
> + /* Check whether #VE info matches the instruction that was decoded. */
> + switch (mmio) {
> + case INSN_MMIO_WRITE:
> + case INSN_MMIO_WRITE_IMM:
> + if (!writable || !(ve->exit_qual & EPT_VIOLATION_ACC_WRITE))
> + return -EFAULT;
> + break;
> + case INSN_MMIO_READ:
> + case INSN_MMIO_READ_ZERO_EXTEND:
> + case INSN_MMIO_READ_SIGN_EXTEND:
> + if (!(ve->exit_qual & EPT_VIOLATION_ACC_READ))
> + return -EFAULT;
> + break;
> + default:
> + WARN_ONCE(1, "Unsupported mmio instruction: %d", mmio);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
--
Kiryl Shutsemau / Kirill A. Shutemov