1
0
mirror of https://github.com/openbsd/src.git synced 2026-06-19 15:53:31 +02:00

A privileged guest can notify an invalid virtio-scsi queue index. The

host-side `vioscsi` device process uses the guest-controlled value as an array
index without a bounds check, interprets adjacent process memory as virtqueue
metadata, and terminates with `SIGSEGV`.
from Quarkslab
ok hshoexer, mlarkin
This commit is contained in:
deraadt
2026-05-28 17:13:17 +00:00
parent b3d0df2d91
commit 6237df7bcd
+17 -2
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: vioscsi.c,v 1.29 2026/02/22 22:54:54 dv Exp $ */
/* $OpenBSD: vioscsi.c,v 1.30 2026/05/28 17:13:17 deraadt Exp $ */
/*
* Copyright (c) 2017 Carlos Cardenas <ccardenas@openbsd.org>
@@ -1501,6 +1501,11 @@ vioscsi_handle_read_10(struct virtio_dev *dev,
__func__, acct->resp_desc->addr, acct->resp_desc->len,
acct->resp_idx, acct->req_idx, acct->idx);
if (acct->resp_desc->len == 0) {
log_warnx("%s: zero-length read_buf descriptor", __func__);
goto free_read_10;
}
/* Check we don't read beyond read_buf boundaries. */
if (acct->resp_desc->len > info->len - chunk_offset) {
log_warnx("%s: descriptor length beyond read_buf len",
@@ -1516,7 +1521,7 @@ vioscsi_handle_read_10(struct virtio_dev *dev,
acct->resp_desc->addr);
goto free_read_10;
}
chunk_offset += acct->resp_desc->len;
chunk_offset += chunk_len;
} while (chunk_offset < info->len);
ret = 1;
@@ -2189,7 +2194,17 @@ vioscsi_notifyq(struct virtio_dev *dev, uint16_t vq_idx)
struct virtio_vq_acct acct;
struct virtio_vq_info *vq_info;
if (vq_idx >= dev->num_queues) {
log_warnx("%s: invalid virtqueue index %u", __func__, vq_idx);
return (0);
}
vq_info = &dev->vq[vq_idx];
if (!vq_info->vq_enabled) {
log_warnx("%s: virtqueue not enabled", __func__);
return (0);
}
vr = vq_info->q_hva;
if (vr == NULL)
fatalx("%s: null vring", __func__);