CVE-2026-98954

Not scored yetLast modified Oct 23, 2026

Description

In the Linux kernel, the following vulnerability has been resolved:

net: always dissect GSO packets in __virtio_net_hdr_to_skb()

Commit 9e8db5913264 ("net: avoid false positives in untrusted gso validation") added a '&& skb->network_header' check before flow-dissecting GSO packets without VIRTIO_NET_HDR_F_NEEDS_CSUM in __virtio_net_hdr_to_skb(), because some callers (such as tun_get_user(), tun_xdp_one(), virtnet_receive_done(), and raw_verify_header()) called virtio_net_hdr_*_to_skb() before initializing skb->network_header and skb->dev.

Because __alloc_skb() and __build_skb_around() zero-initialize skb->network_header to 0 (unlike mac_header and transport_header which are initialized to ~0U), those four callers always had skb->network_header == 0 and bypassed flow dissection in __virtio_net_hdr_to_skb(). More generally, skb->network_header is an offset from skb->head (where 0 is also a valid offset whenever skb_headroom(skb) is 0), not a boolean flag.

Whenever the 'if (gso_type && skb->network_header)' branch was skipped, the fallback 'else if (gso_type)' only pulled nh_min_len + thlen (40 bytes for TCPv4) without dissecting the packet, without validating ip_proto or n_proto, and without setting skb->transport_header.

If the packet has a malformed network header, it is not rejected and a subsequent skb_probe_transport_header() also fails, leaving skb->transport_header at ~0U (0xffff). Similarly, if an IPv4 packet carries IP options (ihl > 5) or an IPv6 packet carries extension headers, pulling only nh_min_len + thlen can leave the TCP header outside skb->head. In both cases, tcp_hdrlen(skb) in skb_gso_transport_seglen() reads out-of-bounds:

BUG: KASAN: slab-out-of-bounds in skb_gso_transport_seglen Read of size 2 by task poc/133 skb_gso_transport_seglen (net/core/gso.c:155) skb_gso_validate_mac_len (net/core/gso.c:270) tbf_enqueue (net/sched/sch_tbf.c:260) dev_qdisc_enqueue (net/core/dev.c:4227) __dev_queue_xmit (net/core/dev.c:4884)

In addition, checking virtio_net_hdr_match_proto() only inside 'if (!skb->protocol)' before flow dissection both skipped validation when skb->protocol was pre-set by the caller and rejected VLAN-tagged frames whose outer L2 protocol is ETH_P_8021Q or ETH_P_8021AD.

Fix this by: 1. Initializing skb->dev and skb->network_header (plus skb->protocol for IFF_TUN) before virtio_net_hdr_*_to_skb() in tun_get_user(), tun_xdp_one(), virtnet_receive_done(), and raw_verify_header(). In tun_get_user(), drop the redundant skb_reset_mac_header(skb) in the IFF_TUN case since __virtio_net_hdr_to_skb() unconditionally resets mac_header. 2. Removing '&& skb->network_header' and the unvalidated 'else if (gso_type)' fallback in __virtio_net_hdr_to_skb() so all GSO packets without VIRTIO_NET_HDR_F_NEEDS_CSUM are flow-dissected, have their transport header pulled into linear data, and have skb->transport_header set. 3. Moving the virtio_net_hdr_match_proto() check to after skb_flow_dissect_flow_keys_basic(), validating keys.basic.n_proto against hdr_gso_type.

Metrics

No CVSS score has been published yet.

Affected software

Source: the vendor's advisory (CNA). NVD analysis pending.

No affected versions have been published.

Timeline

Published
Oct 23, 2026
Last modified
Oct 23, 2026
NVD status
Received

Related CVEs from 2026

CVE-2026-98955In the Linux kernel, the following vulnerability has been resolved: flow_dissector: avoid u16 truncation of skb->len when computing thoff CVE-2026-98956In the Linux kernel, the following vulnerability has been resolved: ASoC: adau1372: allow sleepy powerdown GPIOs gpiod_set_value() emits aCVE-2026-98957In the Linux kernel, the following vulnerability has been resolved: wifi: mt76: mt7915: disable rx napi when removing device Unloading theCVE-2026-98958In the Linux kernel, the following vulnerability has been resolved: wifi: mt76: account non-AQL frames per peer rather than per link The dCVE-2026-989599.8In the Linux kernel, the following vulnerability has been resolved: btrfs: fix xattr replace when multiple xattrs are packed in the same itCVE-2026-98968.8Out of bounds write in V8 in Google Chrome prior to 148.0.7778.216 allowed a remote attacker to execute arbitrary code inside a sandbox via CVE-2026-98960In the Linux kernel, the following vulnerability has been resolved: btrfs: don't stash io_uring encoded data across -EAGAIN Returning -EAGCVE-2026-98961In the Linux kernel, the following vulnerability has been resolved: btrfs: unlock inode and extent in caller when io_uring read extent failCVE-2026-98962In the Linux kernel, the following vulnerability has been resolved: btrfs: free iov when btrfs_uring_read_extent() fails After btrfs_uringCVE-2026-98963In the Linux kernel, the following vulnerability has been resolved: btrfs: always return -EIOCBQUEUED after btrfs_uring_read_extent_endio CVE-2026-989647.5In the Linux kernel, the following vulnerability has been resolved: nvmet: use the local P2P device on metadata allocation failure nvmet_rCVE-2026-989657.5In the Linux kernel, the following vulnerability has been resolved: ice: Restore Ordered MMIO Writes for Tx Doorbells The DQL accounting s
CVE-2026-98954: Unscored | Vulnix