[PATCH] hw/net/virtio-net: check packet size before VLAN tag access in receive_filter()

Laurent Vivier posted 1 patch 2 days, 19 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260722115008.1570510-1-lvivier@redhat.com
Maintainers: "Michael S. Tsirkin" <mst@redhat.com>, Jason Wang <jasowangio@gmail.com>
hw/net/virtio-net.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
[PATCH] hw/net/virtio-net: check packet size before VLAN tag access in receive_filter()
Posted by Laurent Vivier 2 days, 19 hours ago
receive_filter() reads ptr[14..15] to extract the VLAN ID without
checking the packet is large enough. A short frame with VLAN TPID
at bytes 12-13 but no VLAN TCI causes a 2-byte out-of-bounds read.

Add size checks before accessing the Ethernet header and the VLAN
tag fields.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3788
Fixes: f21c0ed97c97 ("qemu:virtio-net: Add VLAN filtering (Alex Williamson)")
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
 hw/net/virtio-net.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index f0e3beb29032..b5b4f025c7c9 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1745,9 +1745,20 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size)
         return 1;
 
     ptr += n->host_hdr_len;
+    size -= n->host_hdr_len;
+
+    if (size < sizeof(struct eth_header)) {
+        return 0;
+    }
 
     if (!memcmp(&ptr[12], vlan, sizeof(vlan))) {
-        int vid = lduw_be_p(ptr + 14) & 0xfff;
+        int vid;
+
+        if (size < 16) {
+            return 0;
+        }
+
+        vid = lduw_be_p(ptr + 14) & 0xfff;
         if (!(n->vlans[vid >> 5] & (1U << (vid & 0x1f))))
             return 0;
     }
-- 
2.54.0
Re: [PATCH] hw/net/virtio-net: check packet size before VLAN tag access in receive_filter()
Posted by Philippe Mathieu-Daudé 2 days, 19 hours ago
On 22/7/26 13:50, Laurent Vivier wrote:
> receive_filter() reads ptr[14..15] to extract the VLAN ID without
> checking the packet is large enough. A short frame with VLAN TPID
> at bytes 12-13 but no VLAN TCI causes a 2-byte out-of-bounds read.
> 
> Add size checks before accessing the Ethernet header and the VLAN
> tag fields.
> 
> Cc: qemu-stable@nongnu.org
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3788
> Fixes: f21c0ed97c97 ("qemu:virtio-net: Add VLAN filtering (Alex Williamson)")
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> ---
>   hw/net/virtio-net.c | 13 ++++++++++++-
>   1 file changed, 12 insertions(+), 1 deletion(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>