Heap OOB read in virtio-net receive_filter VLAN tag parsing

Imported by the "Security Issuer Importer" bot, on behalf of the original reporter who disclosed via qemu-security list:

  • From: Feifan Qian <bea1e@proton.me>
  • Date: 06 May, 2026
  • Message ID: <vsq8Gc2lfZ8LYMT-u-TOyqwWrb_0Xr1mH05yDGiiPUPGo8pD79h7Kob7OOsc13gQPELVh8gNikttOaMED3HJvbinqXgq_26FVPmgjg-fjZI=@proton.me>

NOTE: the original reporter can not be copied on this issue so cannot view this ticket while it remains marked confidential. If further information is needed about the disclosure, contact the reporter directly.

NOTE: this disclosure includes a report.md file which provides a markdown formatted version of the disclosure which may include more information that this bug description.


I am reporting a security vulnerability in QEMU's virtio-net device emulation. The receive_filter() function in hw/net/virtio-net.c performs an out-of-bounds heap read when processing undersized VLAN-tagged Ethernet frames. When a packet smaller than (host_hdr_len + 16) bytes arrives with VLAN TPID 0x8100 at bytes 12-13, the function reads 2 bytes beyond the packet boundary to extract a VLAN ID. These leaked bytes come from host QEMU process heap memory and are used as an index into the VLAN filter table, with the accept/drop result observable by the attacker through network behavior.

Affected versions: QEMU git master (11.0.50) as of commit ac0cc20a. The vulnerable code path exists in all versions where receive_filter() accesses ptr[14..15] without validating size against host_hdr_len. The vulnerability is reachable when virtio-net operates in userspace receive mode (vhost=off) with host_hdr_len=0 (no vnet_hdr offload negotiated). Under default tap backend configuration with vnet_hdr enabled, the effective minimum safe packet size is larger, limiting reachability.

Security impact: An attacker on the same L2 network segment as the VM can craft a 14-byte VLAN-tagged Ethernet frame that causes QEMU to read 2 bytes of adjacent heap memory. By sending priming frames followed by probe frames against different VLAN filter configurations, the attacker can infer heap memory content 2 bytes at a time via the accept/drop oracle. This constitutes information disclosure of host process memory (CVSS v3.1: 4.3, Medium, AV:A/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N). Under rare conditions where the packet buffer ends at a page boundary, the OOB read could cross into an unmapped page and trigger a SIGSEGV (denial of service).

A detailed technical report with full reproduction steps, a proof-of-concept that demonstrates the OOB read with AddressSanitizer, and a patch to reproduce are attached as disclosure.zip. The PoC exercises the actual receive_filter code path in an ASAN-instrumented QEMU build and catches the 2-byte heap-buffer-overflow at the exact allocation boundary.

I am happy to provide further details, coordinate on a disclosure timeline, or assist with testing a fix. I can be reached at this email address.

disclosure.zip report.md