OOB read/write in KVM sev_es_string_io

We discussed this vulnerability during Episode 104 on 30 November 2021

Out-of-bounds (OOB) access in the VMGExit handler, which is triggered for string I/O instructions. The sev_es_string_io() function is responsible for doing the string copy between the unencrypted guest memory regions and the virtualized target. When doing so, it’ll setup a scratch buffer at svm->ghcb_sa (GHCB is short for Guest-Hypervisor-Communication-Block), and it’ll set it up using guest-controlled values for the length, I/O access size, and contents for the scratch buffer. When the control flow reaches emulator_pio_out() for outgoing I/O, it’ll copy the contents of the scratch buffer to the virtual CPU pio data using the I/O access size multiplied against the provided length. The problem is, pio_data is only one page size in length. If you provide a count or size that makes the memcpy() go beyond one virtual page, there’s an out of bounds access on adjacent pages.

Since this bug is in both the input and output paths, it provides an OOB read and an OOB write. The patch here was to ensure you couldn’t provide a size that would exceed the page size of the system.