The vulnerability lies in the sys_read implementation used by the RISC Zero zkVM guest. When a guest program requests to read data from the host, the underlying functions responsible for handling this I/O operation contained a critical memory safety flaw. The root cause was that the code trusted the number of bytes reported as 'read' by the host. This value was then used in pointer arithmetic to calculate the memory address for the next write operation.
A malicious host could exploit this by providing a crafted response, claiming to have written a number of bytes larger than the actual buffer allocated by the guest. This would cause the guest to write subsequent data out-of-bounds, leading to a buffer overflow. This overflow could be leveraged to overwrite critical memory, such as return addresses on the stack, to achieve arbitrary code execution within the guest, completely compromising the integrity of the zkVM's computation.
The analysis of the patch identified three key functions involved in this vulnerable process:
risc0_zkvm_platform::syscall::sys_read: The primary entry point for the guest's read operations.
risc0_zkvm_platform::syscall::sys_read_internal: An internal helper that performed the vulnerable chunked reading logic.
risc0_zkos_v1compat::zkvm::ecall_software: A kernel-level function in the v1 compatibility layer that also contained a flawed chunking implementation for large reads.
The fix involved a major refactoring of the I/O subsystem. The vulnerable, manual pointer arithmetic was replaced with safer Rust slice operations. Crucially, checks were added in the new kernel-level sys_read implementation to validate that the number of bytes read from the host does not exceed the size of the guest's buffer, thereby mitigating the buffer overflow vulnerability.