The RSC receive path parses incoming frames at guest_hdr_len byte
offsets, but the backend buffer contains only host_hdr_len bytes of vnet
header. If the lengths differ, RSC would read at the wrong offset and
cause an OOB read.
This is no longer possible after the previous patch, but the assumption
seem fragile. Along the defense in depth lines, let's validate. To
ensure we are not breaking any valid setups by mistake, warn and fall
back to the normal receive path when host_hdr_len != guest_hdr_len.
Fixes: CVE-2026-63321
Fixes: 2974e916df ("virtio-net: support RSC v4/v6 tcp traffic for Windows HCK")
Cc: Jason Wang <[email protected]>
Cc: Yuri Benditovich <[email protected]>
Cc: Wei Xu <[email protected]>
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3623
Signed-off-by: Michael S. Tsirkin <[email protected]>
---
hw/net/virtio-net.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index f0e3beb290..2761644dfd 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -2674,6 +2674,13 @@ static ssize_t virtio_net_receive(NetClientState *nc,
const uint8_t *buf,
{
VirtIONet *n = qemu_get_nic_opaque(nc);
if ((n->rsc4_enabled || n->rsc6_enabled)) {
+ /* this never happens with existing backends, but just in case. */
+ if (n->host_hdr_len != n->guest_hdr_len) {
+ warn_report_once("virtio-net: host_hdr_len %zu != guest_hdr_len
%zu, "
+ "skipping RSC",
+ n->host_hdr_len, n->guest_hdr_len);
+ return virtio_net_do_receive(nc, buf, size);
+ }
return virtio_net_rsc_receive(nc, buf, size);
} else {
return virtio_net_do_receive(nc, buf, size);
--
MST