From: Laurent Vivier <[email protected]> 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: [email protected] Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3788 Fixes: f21c0ed97c97 ("qemu:virtio-net: Add VLAN filtering (Alex Williamson)") Signed-off-by: Laurent Vivier <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Reviewed-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Message-ID: <[email protected]> (cherry picked from commit 5d85a09554fb66e18107cfbfa4e6b637bf4e2508) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 4362e866d70..ad4b0d8d9a1 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1756,12 +1756,16 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size) } 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; - /* Truncated vlan packet */ - if (size < n->host_hdr_len + 16) { + if (size < 16) { return 0; } vid = lduw_be_p(ptr + 14) & 0xfff; -- 2.47.3
