On 26/8/26 20:17, Paolo Bonzini wrote:
A guest with an attached scsi-hd can force QEMU's SCSI disk emulation to read roughly 60 KiB past the end of a heap buffer, copying that out of bounds host memory into the guest's own disk image.WRITE SAME computes the request transfer length at dev->blocksize when the request is prepared and sets cmd->xfer from dev->blocksize. scsi_disk_emulate_command() then uses cmd->xfer as the size of the request buffer. However, MODE SELECT can race with the WRITE SAME command and guest raise the logical block size to any value whose low bits fit 0xfe00, up to 65024. In the presence of this race, scsi_disk_emulate_write_same() will read from memory as many bytes as indicated by the *new* dev->blocksize, and write it to disk. The read length in WRITE SAME must be bounded by the buffer that was actually allocated, not by the mutable s->qdev.blocksize, so clamp the length used against inbuf to r->buflen. Re-validating req->cmd.xfer against the current block size would not work because the race is intrinsic in the SCSI protocol. I am not sure if this is exploitable with virtio-scsi and other SG-capable HBAs, because it should process the WRITE SAME input immediately, without letting the MODE SELECT command race with it; but probably it is because s->qdev.blocksize is accessed without a lock. Fixes: 356c4c441ec ("scsi-disk: allow MODE SELECT block descriptor to set the block size", 2022-07-13) Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4365 Signed-off-by: Paolo Bonzini <[email protected]> --- hw/scsi/scsi-disk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
