Skip to main content
Vulnerability Database/CVE-2026-98850

CVE-2026-98850: Linux Kernel TX_RING DOS Vulnerability

CVE-2026-98850 is a denial of service vulnerability in the Linux kernel affecting the TX_RING packet handling that allows attackers to crash systems. This post explains its technical details, affected versions, impact, and mitigation steps.

Published:

CVE-2026-98850 Overview

CVE-2026-98850 is a Linux kernel vulnerability in the net/packet subsystem. The flaw resides in tpacket_snd(), which drains every SEND_REQUEST frame in a TX_RING and accumulates each valid packet length into the signed integer len_sum. Because userspace can recycle completed frames concurrently, a single blocking send call is not bounded by the ring size.

After enough successful transmissions, len_sum wraps into the negative range. A crafted sequence can produce the value 0xfffffdef, which equals -EIOCBQUEUED. sock_sendmsg_nosec() treats that return as impossible and triggers a BUG().

Critical Impact

A local attacker holding CAP_NET_RAW can panic the host kernel on systems configured to oops-on-panic.

Affected Products

  • Linux kernel (net/packet subsystem, tpacket_snd() TX_RING path)
  • Linux 7.3-rc4 confirmed vulnerable on arm64 via a two-thread TPACKET_V2 reproducer
  • Stable branches fixed by commits 2cf81fc, 69ca64b, 9fd63d2, ae169d3, and be12b22

Discovery Timeline

  • 2026-10-18 - CVE-2026-98850 published to NVD
  • 2026-10-21 - Last updated in NVD database

Technical Details for CVE-2026-98850

Vulnerability Analysis

The AF_PACKET TX_RING interface lets userspace enqueue frames in a shared ring buffer for high-throughput transmission. The kernel helper tpacket_snd() iterates over each ring slot flagged TP_STATUS_SEND_REQUEST, transmits the packet, and adds the frame length to the signed integer accumulator len_sum. The function returns len_sum to the caller through sock_sendmsg_nosec().

The accumulator is not bounded by ring capacity because userspace can mark completed slots as ready again while the kernel is still iterating. A cooperative producer thread can therefore keep refilling the ring during one blocking send, allowing len_sum to grow without limit.

Once len_sum crosses INT_MAX, the value wraps negative. A specific pattern (65536 frames of 65535 bytes followed by one 65007-byte frame) yields 0xfffffdef, numerically equal to -EIOCBQUEUED. The upper socket layer interprets -EIOCBQUEUED as a protocol-impossible result and invokes BUG(), panicking the kernel on hosts configured to panic on oops.

Root Cause

The root cause is an unchecked signed integer accumulation [CWE-190] inside tpacket_snd(). The function trusts that the ring size caps total bytes transmitted per call, but concurrent userspace recycling breaks that assumption.

Attack Vector

Exploitation requires local code execution with CAP_NET_RAW, which is needed to open an AF_PACKET socket and bind a PACKET_TX_RING. The attacker runs two cooperating threads: one issuing a blocking sendto() on the TX_RING socket and another resetting slot status to TP_STATUS_SEND_REQUEST as frames complete. After enough iterations the accumulator wraps negative, the BUG fires, and the kernel panics.

No exploitation code is published alongside the fix. The commit message describes the reproducer in prose: a two-thread TPACKET_V2 program on arm64 Linux 7.3-rc4 triggered the BUG, and the patched kernel instead returned the expected positive short count. Readers can consult the upstream fix commit for the exact code change.

Detection Methods for CVE-2026-98850

Indicators of Compromise

  • Unexpected kernel panic or oops referencing sock_sendmsg_nosec or tpacket_snd in net/packet/af_packet.c.
  • Processes holding CAP_NET_RAW that open AF_PACKET sockets and configure PACKET_TX_RING with sustained high-volume sends.
  • dmesg entries containing kernel BUG at net/socket.c immediately after AF_PACKET traffic from a non-root user namespace.

Detection Strategies

  • Audit syscall=socket events where a0=17 (AF_PACKET) and correlate with setsockopt calls for PACKET_TX_RING using Linux audit rules.
  • Monitor /proc/net/packet for processes with unusually large TX ring allocations and persistent send activity.
  • Flag non-root processes acquiring CAP_NET_RAW through capability-aware EDR telemetry.

Monitoring Recommendations

  • Ingest kernel ring-buffer logs into a centralized log store and alert on BUG, Oops, and general protection fault keywords tied to af_packet symbols.
  • Track unplanned reboots and kernel crash dumps across Linux fleets; sudden clustering may indicate exploitation attempts.
  • Enforce least-privilege reviews that flag binaries or containers requesting CAP_NET_RAW outside of networking appliances.

How to Mitigate CVE-2026-98850

Immediate Actions Required

  • Apply the upstream Linux kernel patch series referenced below and reboot affected hosts.
  • Remove CAP_NET_RAW from workloads that do not require raw packet access, including unprivileged containers and user namespaces.
  • Disable kernel.panic_on_oops where operationally acceptable to reduce availability impact until patching completes.

Patch Information

The fix stops the loop before the next frame would push len_sum past INT_MAX, returning a positive short count and leaving the pending frame for a later send call. Stable-tree commits are available at commit 2cf81fc, commit 69ca64b, commit 9fd63d2, commit ae169d3, and commit be12b22. Distribution kernels should ship backports; verify your vendor advisory before deployment.

Workarounds

  • Restrict AF_PACKET socket creation through seccomp profiles on container runtimes and systemd units.
  • Drop CAP_NET_RAW from Docker and Kubernetes pods using securityContext.capabilities.drop: ["NET_RAW"].
  • Set sysctl kernel.unprivileged_userns_clone=0 where feasible to prevent capability acquisition via user namespaces.
bash
# Configuration example: drop CAP_NET_RAW and block AF_PACKET at runtime
# Kubernetes pod securityContext
# securityContext:
#   capabilities:
#     drop: ["NET_RAW"]

# Verify currently loaded kernel version
uname -r

# Audit processes that currently hold CAP_NET_RAW
for pid in $(ls /proc | grep -E '^[0-9]+$'); do
  grep -l 'CapEff' /proc/$pid/status 2>/dev/null | \
    xargs -I{} awk '/CapEff/ {print "'$pid' " $2}' {}
done

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.