@samitouri / QOSamiQemu / commits / aeea0c2804

virtio-blk: add missing VIRTIO_BLK_T_SCSI_CMD size check (CVE-2026-48914)

Check that the iovec containing struct virtio_scsi_inhdr is large enough before storing an error value there. Feifan Qian <bea1e@proton.me> pointed out that this can be used to corrupt heap memory when the descriptor uses an MMIO address and a length of 1, forcing QEMU to allocate a 1-byte heap bounce buffer. virtio_stl_p() stores 4 bytes and therefore corrupts whatever is beyond the bounce buffer. Fixes: CVE-2026-48914 Fixes: f34e73cd69bd ("virtio-blk: report non-zero status when failing SG_IO requests") Reported-by: Feifan Qian <bea1e@proton.me> Cc: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Message-ID: <20260526154957.1741622-1-stefanha@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>

Stefan Hajnoczi committed May 26, 2026 at 11:49 UTC aeea0c2804c42f24915467a1e4c70e649e39b8e0
1 file changed +7 -1
hw/block/virtio-blk.c
+7 -1
@@ -199,10 +199,16 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
199
200 /*
201 * The scsi inhdr is placed in the second-to-last input segment, just
202 - * before the regular inhdr.
202 + * before the regular inhdr. VIRTIO implementations normally do not rely on
203 + * the precise message framing, but legacy implementations did and so we do
204 + * too for the legacy virtio-blk SCSI request type.
205 *
206 * Just put anything nonzero so that the ioctl fails in the guest.
207 */
208 + if (elem->in_sg[elem->in_num - 2].iov_len != sizeof(*scsi)) {
209 + status = VIRTIO_BLK_S_IOERR;
210 + goto fail;
211 + }
212 scsi = (void *)elem->in_sg[elem->in_num - 2].iov_base;
213 virtio_stl_p(vdev, &scsi->errors, 255);
214 status = VIRTIO_BLK_S_UNSUPP;