Like a hallway door whose lock arithmetic overflows to 'open' when you shove too wide a key into it
CVE-2026-81000, nicknamed TUNderflow, is an integer-underflow flaw in the Linux kernel's TUN/TAP virtual networking subsystem (drivers/net/tun.c). The function tun_get_user() reuses tun->align both as skb headroom and as the linear-data budget. When Open vSwitch (or any stacked device) propagates an oversized headroom request, SKB_MAX_HEAD(align) underflows, turning good_linear negative. That value wraps when cast to size_t, and tun_alloc_skb() places skb->data outside the allocated head — giving an attacker a kernel out-of-bounds write primitive. The bug was introduced in kernel 4.6 (commit eaea34b, circa 2016) and affects every unpatched kernel through 7.2.3. Fixes landed in stable branches 5.10.270, 5.15.221, 6.1.188, 6.6.157, 6.12.109, 6.18.50, and 7.2.4.
The vendor CVSS of 7.8 HIGH is reasonable for the raw primitive — full C/I/A at local scope. Ubuntu downgraded to Medium priority, likely weighting the local-only attack vector. noisgate keeps this at HIGH 7.0: the local-access requirement is real friction, but TUN/TAP is *the* networking plumbing for containers and virtual machines, meaning the highest-value deployment roles (Kubernetes nodes, KVM hypervisors, CI runners) are exactly where TUN is most active. A public PoC exists. The vendor severity is directionally correct; we shave the score slightly for the local-only, namespace-dependent chain but do not drop the bucket.
5 steps from start to impact.
Obtain local shell on target host
- Local user-level access on a Linux host running an affected kernel (4.6 – 7.2.3)
- Requires a prior access vector — not remotely exploitable on its own
Verify unprivileged user namespaces are enabled
kernel.unprivileged_userns_clone=1 or the default on Ubuntu/Fedora). This lets a non-root user create network namespaces and TUN devices. RHEL 8+/SLES with restricted defaults block this step without additional configuration.- Unprivileged user namespaces enabled (default on Ubuntu, Fedora, Debian; restricted on RHEL/SLES)
- RHEL/SLES defaults block unprivileged namespace creation
- Some hardened deployments explicitly disable via sysctl
clone(CLONE_NEWUSER) syscall; Falco container-runtime rulesCreate TUN device and trigger oversized headroom
rx_headroom value to propagate through a stacked OVS or bridge path. This causes SKB_MAX_HEAD(align) to underflow in tun_get_user().- Ability to create TUN/TAP device (via user namespace or
/dev/net/tunaccess) - OVS or stacked device path that propagates headroom
- PoC is tuned per distro and kernel version — not a universal one-click exploit
- Requires specific OVS or bridge topology to propagate the headroom value
Exploit OOB write for kernel code execution
linear value causes tun_alloc_skb() to allocate a buffer whose skb->data pointer lands outside the head. The attacker crafts packet data to overwrite adjacent slab objects, pivoting to arbitrary kernel code execution. Standard heap-spray techniques (msg_msg, pipe_buffer) apply.- Kernel heap layout amenable to controlled overwrite
- Knowledge of target kernel's slab allocator and KASLR base
- KASLR, SMEP, SMAP, and CFI raise the bar for reliable exploitation
- Heap grooming is probabilistic and may cause kernel panics on failure
Escalate to root
commit_creds(prepare_kernel_cred(0))) to gain uid 0. From a container, this is a container escape to the host kernel — full node compromise.- Successful kernel code execution from step 4
- Kernel lockdown mode and integrity verification may limit post-exploitation persistence
The supporting signals.
| In-the-Wild Exploitation | Not confirmed. No CISA KEV listing. No vendor advisories cite active campaigns. Disclosed 2026-09-11 as part of a four-CVE LPE batch (DirtyAH6, TUNderflow, PPPoEject, DiagSpill). |
|---|---|
| Proof-of-Concept | Public PoC exists, disclosed alongside the advisory. Described as distro- and kernel-version-specific; not a universal exploit. Researcher recommends throwaway VMs only. Available in aggregator repos (e.g., SecureWithUmer/CVE-2026-PoCs). |
| EPSS | 0.00164 (0.164% probability of exploitation in 30 days) — low, but PoC availability may cause this to climb. |
| KEV Status | Not listed as of 2026-09-18. |
| CVSS Vector | CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H — Local attack vector, low complexity, low privileges, no user interaction. Scope unchanged. Full CIA impact. The *local-only* vector is the key limiter. |
| Affected Versions | Linux kernel 4.6 through 7.2.3 (introduced by commit eaea34b in 2016). Affects virtually every maintained LTS and stable branch prior to the fix. |
| Fixed Versions | 5.10.270, 5.15.221, 6.1.188, 6.6.157, 6.12.109, 6.18.50, 7.2.4, 7.3-rc1. Ubuntu/Debian/RHEL backports in progress — check distro trackers. |
| Scanning / Exposure | Not remotely exploitable — no Shodan/GreyNoise/Censys exposure surface. Vulnerability is local-only. Asset inventory of kernel versions is the relevant exposure metric. |
| Disclosure | 2026-09-11 — reported to kernel security team mid-July 2026 by Asim Viladi Oglu Manizada. Part of the 'LPE Quartet' disclosure batch. |
| Researcher | Asim Viladi Oglu Manizada — reported mid-July 2026. AI-assisted analysis methods reportedly used in discovery. |
noisgate verdict.
The single most decisive factor sustaining HIGH is the role multiplier: TUN/TAP is the foundational networking primitive for containers and virtual machines, meaning Kubernetes nodes, KVM hypervisors, and CI runners — all high-value roles — are canonical deployments where this kernel OOB-write chain succeeds and ends in full host compromise. The local-only attack vector prevents an upgrade to CRITICAL but cannot pull below the HIGH floor given a public PoC and the container-host blast radius.
Why this verdict
- Public PoC with LPE primitive: A working proof-of-concept exists that converts the integer underflow into a kernel OOB write → root. While distro-specific tuning is needed, the primitive is sound and the technique (heap spray via
msg_msg/pipe_buffer) is well-understood in the exploit-dev community. - Role multiplier — container and virtualization hosts: TUN/TAP is not an optional module; it is *the* virtual networking layer for Docker, Kubernetes, and KVM. On a Kubernetes node, this chain is: container workload (low-priv shell) → user namespace → TUN underflow → kernel code exec → container escape → full node compromise. ≥30% of the installed base of Linux servers running containers have TUN as an active, attacker-reachable component. The blast radius on these hosts is node-level, potentially cluster-level with lateral movement. This floors the verdict at HIGH.
- Local-only vector is meaningful friction: AV:L means the attacker must already have a foothold. This is not a drive-by or network worm. Every exploitation scenario presupposes a prior compromise stage, which compounds the difficulty. This prevents upgrading to CRITICAL.
- Namespace dependency narrows the population: RHEL and SLES restrict unprivileged user namespaces by default. Ubuntu, Fedora, and Debian enable them. Roughly 50-60% of enterprise Linux deployments (Ubuntu/Debian-heavy cloud fleets) are in the permissive default; the remainder require explicit enablement or a different attack path.
- No active exploitation or KEV listing: EPSS is 0.164%. No campaigns observed. The PoC is public but tuned, not weaponized at scale. This argues against emergency treatment but does not reduce the underlying severity of the primitive.
Why not higher?
CRITICAL would require either active exploitation, a remote attack vector, or a wormable chain. CVE-2026-81000 is strictly local (AV:L), has no confirmed in-the-wild abuse, and the PoC requires per-distro tuning. The scope is Unchanged (S:U) — it does not inherently chain across trust boundaries without a prior foothold. Container escape is possible but starts from an already-compromised workload, not from the network.
Why not lower?
MEDIUM would undercount the blast radius on container infrastructure. TUN/TAP is not a niche module — it is foundational to container networking, meaning Kubernetes nodes and KVM hypervisors are canonical targets where the chain succeeds. A public PoC exists with a proven kernel-memory-corruption primitive. The affected version range spans a decade of kernels (4.6–7.2.3). Ubuntu's Medium rating underweights the role multiplier for virtualized and containerized infrastructure.
What to do — in priority order.
- Disable unprivileged user namespaces — Set
kernel.unprivileged_userns_clone=0oruser.max_user_namespaces=0via sysctl. This blocks the primary exploitation path without affecting root-level container runtimes (Docker/containerd run as root and create namespaces with CAP_SYS_ADMIN). Deploy within 30 days per the noisgate mitigation SLA for HIGH. Test on staging first — some workloads (Flatpak, Chrome sandbox, rootless Podman) depend on unprivileged namespaces. - Restrict /dev/net/tun access — Tighten device permissions or use a udev rule to limit
/dev/net/tunto specific groups (e.g.,kvm,libvirt). This reduces the attack surface for non-containerized hosts. Deploy within 30 days. - Deploy Falco or Tetragon runtime rules — Add detection rules for unexpected
clone(CLONE_NEWUSER)syscalls, TUN device creation from non-standard processes, and uid-0 transitions without correspondingsudo/su. These provide detection-in-depth while patching progresses. - Prioritize kernel patching on container and VM hosts — Kubernetes nodes, KVM hypervisors, and CI runners should be first in the patching queue. These are where TUN is most active and the blast radius is highest. Target the noisgate remediation SLA of 180 days, but front-load high-value roles.
- Network segmentation / firewalling — This is a local privilege escalation, not a network attack. Firewalls and network ACLs have zero effect on exploitation.
- WAF / IDS / IPS — No network signature exists because the attack occurs entirely within the kernel on the local host. Network-layer detection tools cannot see it.
- SELinux / AppArmor alone — While MAC policies can limit what a compromised process does post-exploitation, they do not prevent the kernel memory corruption itself. The OOB write occurs in kernel space, bypassing userland MAC enforcement. They help contain blast radius but do not block the root cause.
Crowdsourced verification payload.
Run this script on each target Linux host as any user. It checks the running kernel version against known-fixed versions. Invoke with: bash check_cve_2026_81000.sh. No elevated privileges required.
#!/bin/bash
# CVE-2026-81000 (TUNderflow) — kernel version check
# Checks running kernel against fixed stable branches.
# Exit codes: 1=VULNERABLE, 0=PATCHED, 2=UNKNOWN
set -euo pipefail
KERNEL=$(uname -r)
echo "[*] Running kernel: $KERNEL"
# Extract major.minor.patch from kernel version string
MAJOR=$(echo "$KERNEL" | cut -d. -f1)
MINOR=$(echo "$KERNEL" | cut -d. -f2)
PATCH=$(echo "$KERNEL" | cut -d. -f3 | cut -d- -f1)
# version_ge: returns 0 if $1.$2.$3 >= $4.$5.$6
version_ge() {
local a1=$1 a2=$2 a3=$3 b1=$4 b2=$5 b3=$6
if [ "$a1" -gt "$b1" ] 2>/dev/null; then return 0; fi
if [ "$a1" -lt "$b1" ] 2>/dev/null; then return 1; fi
if [ "$a2" -gt "$b2" ] 2>/dev/null; then return 0; fi
if [ "$a2" -lt "$b2" ] 2>/dev/null; then return 1; fi
if [ "$a3" -ge "$b3" ] 2>/dev/null; then return 0; fi
return 1
}
if [ -z "$MAJOR" ] || [ -z "$MINOR" ] || [ -z "$PATCH" ]; then
echo "UNKNOWN — could not parse kernel version: $KERNEL"
exit 2
fi
# Fixed versions per stable branch:
# 5.10.270, 5.15.221, 6.1.188, 6.6.157, 6.12.109, 6.18.50, 7.2.4
# Vulnerable range: 4.6 through unfixed branches
# Check if kernel predates the vulnerable commit (< 4.6)
if version_ge "$MAJOR" "$MINOR" "$PATCH" 4 6 0; then
: # potentially vulnerable, continue checks
else
echo "PATCHED — kernel $KERNEL predates the vulnerable code (introduced in 4.6)"
exit 0
fi
VULN=1
case "${MAJOR}.${MINOR}" in
5.10) version_ge "$MAJOR" "$MINOR" "$PATCH" 5 10 270 && VULN=0 ;;
5.15) version_ge "$MAJOR" "$MINOR" "$PATCH" 5 15 221 && VULN=0 ;;
6.1) version_ge "$MAJOR" "$MINOR" "$PATCH" 6 1 188 && VULN=0 ;;
6.6) version_ge "$MAJOR" "$MINOR" "$PATCH" 6 6 157 && VULN=0 ;;
6.12) version_ge "$MAJOR" "$MINOR" "$PATCH" 6 12 109 && VULN=0 ;;
6.18) version_ge "$MAJOR" "$MINOR" "$PATCH" 6 18 50 && VULN=0 ;;
7.2) version_ge "$MAJOR" "$MINOR" "$PATCH" 7 2 4 && VULN=0 ;;
7.3|7.4|7.5|7.6|7.7|7.8|7.9)
VULN=0 ;; # 7.3+ includes the fix
*)
if [ "$MAJOR" -ge 8 ] 2>/dev/null; then
VULN=0
fi
;;
esac
# Also check: is TUN module loaded or built-in?
TUN_STATUS="unknown"
if lsmod 2>/dev/null | grep -q '^tun '; then
TUN_STATUS="loaded"
elif [ -f /lib/modules/$(uname -r)/kernel/drivers/net/tun.ko* ] 2>/dev/null; then
TUN_STATUS="available (not loaded)"
elif grep -q 'CONFIG_TUN=y' /boot/config-$(uname -r) 2>/dev/null; then
TUN_STATUS="built-in"
fi
echo "[*] TUN module status: $TUN_STATUS"
# Check unprivileged userns
USERNS="unknown"
if [ -f /proc/sys/kernel/unprivileged_userns_clone ]; then
USERNS=$(cat /proc/sys/kernel/unprivileged_userns_clone)
[ "$USERNS" = "1" ] && USERNS="enabled (exploitable)" || USERNS="disabled (mitigated)"
elif [ -f /proc/sys/user/max_user_namespaces ]; then
VAL=$(cat /proc/sys/user/max_user_namespaces)
[ "$VAL" -gt 0 ] 2>/dev/null && USERNS="enabled (max=$VAL)" || USERNS="disabled (mitigated)"
else
USERNS="likely enabled (no restriction sysctl found)"
fi
echo "[*] Unprivileged user namespaces: $USERNS"
if [ "$VULN" -eq 0 ]; then
echo "PATCHED — kernel $KERNEL is at or above the fix for this branch."
exit 0
else
echo "VULNERABLE — kernel $KERNEL is below the fix for CVE-2026-81000."
exit 1
fiIf you remember one thing.
sysctl kernel.unprivileged_userns_clone=0) on hosts that don't need rootless containers; this blocks the primary PoC path. Per the noisgate mitigation SLA for HIGH, deploy compensating controls within 30 days (by 2026-10-18). Per the noisgate remediation SLA, apply the vendor kernel patch (5.10.270 / 5.15.221 / 6.1.188 / 6.6.157 / 6.12.109 / 6.18.50 / 7.2.4+) within 180 days (by 2027-03-17), but front-load high-value container and virtualization hosts into your next maintenance window. No active exploitation is confirmed and this is not KEV-listed, so emergency out-of-cycle patching is not warranted — but do not let the local-only vector lull you into deprioritizing this across your container fleet.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.