git: 15198bfd7437 - main - virtio: Validate host-supplied used lengths
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 03 Oct 2026 12:41:59 UTC
The branch main has been updated by kfv:
URL: https://cgit.FreeBSD.org/src/commit/?id=15198bfd7437a616e66342be3c672da0b523e710
commit 15198bfd7437a616e66342be3c672da0b523e710
Author: Faraz Vahedi <kfv@FreeBSD.org>
AuthorDate: 2026-10-03 12:39:36 +0000
Commit: Faraz Vahedi <kfv@FreeBSD.org>
CommitDate: 2026-10-03 12:39:36 +0000
virtio: Validate host-supplied used lengths
virtio_console used the host-supplied used lengths without
validation, so a host could report a length larger than
the buffer, causing the receive and control paths to read
past the end of it. Clamp to the buffer size.
vtnet already rejected used lengths larger than the buffer,
but performed the check after converting the length to an
int, so a length larger than INT_MAX would become negative
and bypass the check. Reject such frames early before the
conversion, and count them in ierrors and rx_frame_too_large.
Reviewed by: markj
Approved by: fuz (mentor)
Differential Revision: https://reviews.freebsd.org/D60092
---
sys/dev/virtio/console/virtio_console.c | 2 ++
sys/dev/virtio/network/if_vtnet.c | 5 ++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/sys/dev/virtio/console/virtio_console.c b/sys/dev/virtio/console/virtio_console.c
index 81ffd7058f06..7dc6b531ea0e 100644
--- a/sys/dev/virtio/console/virtio_console.c
+++ b/sys/dev/virtio/console/virtio_console.c
@@ -922,6 +922,7 @@ vtcon_ctrl_task_cb(void *xsc, int pending)
if (control == NULL)
break;
+ len = min(len, VTCON_CTRL_BUFSZ);
if (len > sizeof(struct virtio_console_control)) {
data = (void *) &control[1];
data_len = len - sizeof(struct virtio_console_control);
@@ -1320,6 +1321,7 @@ again:
deq = 0;
while ((buf = virtqueue_dequeue(vq, &len)) != NULL) {
+ len = min(len, VTCON_BULK_BUFSZ);
for (i = 0; i < len; i++) {
#if defined(KDB)
if (port->vtcport_flags & VTCON_PORT_FLAG_CONSOLE)
diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c
index 15dd50e7df77..f85b02fe18aa 100644
--- a/sys/dev/virtio/network/if_vtnet.c
+++ b/sys/dev/virtio/network/if_vtnet.c
@@ -2190,7 +2190,10 @@ vtnet_rxq_eof(struct vtnet_rxq *rxq)
mp = mp->m_next;
}
- if (len < sc->vtnet_hdr_size + ETHER_HDR_LEN) {
+ if (synced < len ||
+ len < sc->vtnet_hdr_size + ETHER_HDR_LEN) {
+ if (synced < len)
+ sc->vtnet_stats.rx_frame_too_large++;
rxq->vtnrx_stats.vrxs_ierrors++;
vtnet_rxq_discard_buf(rxq, m);
continue;