← Back to Feed CACHED · 2026-09-18 11:48:05 · CACHE_KEY CVE-2026-81000
CVE-2026-81000 · CWE-191 · Disclosed 2026-09-11

In the Linux kernel

ASSESSED — NOISGATE
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

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.

"Kernel LPE via TUN integer underflow — public PoC, local-only, floors at HIGH on container hosts"
02 · The Attack Path

5 steps from start to impact.

STEP 01

Obtain local shell on target host

The attacker needs an unprivileged local shell. In container environments this is the default starting position — any workload container provides it. On bare-metal servers it requires prior compromise via another vector (phishing, exposed service, SSH credential).
Conditions required:
  • Local user-level access on a Linux host running an affected kernel (4.6 – 7.2.3)
Where this breaks in practice:
  • Requires a prior access vector — not remotely exploitable on its own
Detection/coverage: EDR process-creation telemetry; SSH login auditing
STEP 02

Verify unprivileged user namespaces are enabled

The PoC relies on unprivileged user namespaces (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.
Conditions required:
  • Unprivileged user namespaces enabled (default on Ubuntu, Fedora, Debian; restricted on RHEL/SLES)
Where this breaks in practice:
  • RHEL/SLES defaults block unprivileged namespace creation
  • Some hardened deployments explicitly disable via sysctl
Detection/coverage: Auditd rules on clone(CLONE_NEWUSER) syscall; Falco container-runtime rules
STEP 03

Create TUN device and trigger oversized headroom

The attacker creates a user-namespace-owned network stack, attaches a TUN device, and arranges for an oversized rx_headroom value to propagate through a stacked OVS or bridge path. This causes SKB_MAX_HEAD(align) to underflow in tun_get_user().
Conditions required:
  • Ability to create TUN/TAP device (via user namespace or /dev/net/tun access)
  • OVS or stacked device path that propagates headroom
Where this breaks in practice:
  • 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
Detection/coverage: Kernel KASAN (if compiled in) will flag the OOB access; most production kernels lack KASAN
STEP 04

Exploit OOB write for kernel code execution

The underflowed 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.
Conditions required:
  • Kernel heap layout amenable to controlled overwrite
  • Knowledge of target kernel's slab allocator and KASLR base
Where this breaks in practice:
  • KASLR, SMEP, SMAP, and CFI raise the bar for reliable exploitation
  • Heap grooming is probabilistic and may cause kernel panics on failure
Detection/coverage: Kernel oops/panic logs; crash dump analysis; EDR kernel-level telemetry
STEP 05

Escalate to root

With kernel code execution, the attacker overwrites current task credentials (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.
Conditions required:
  • Successful kernel code execution from step 4
Where this breaks in practice:
  • Kernel lockdown mode and integrity verification may limit post-exploitation persistence
Detection/coverage: uid change without corresponding sudo/su; container escape detection in Falco/Tetragon
03 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNot 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-ConceptPublic 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).
EPSS0.00164 (0.164% probability of exploitation in 30 days) — low, but PoC availability may cause this to climb.
KEV StatusNot listed as of 2026-09-18.
CVSS VectorCVSS: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 VersionsLinux 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 Versions5.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 / ExposureNot remotely exploitable — no Shodan/GreyNoise/Censys exposure surface. Vulnerability is local-only. Asset inventory of kernel versions is the relevant exposure metric.
Disclosure2026-09-11 — reported to kernel security team mid-July 2026 by Asim Viladi Oglu Manizada. Part of the 'LPE Quartet' disclosure batch.
ResearcherAsim Viladi Oglu Manizada — reported mid-July 2026. AI-assisted analysis methods reportedly used in discovery.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (7.0/10)

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.

HIGH Vulnerability existence and affected version range
MEDIUM Exploitability in hardened production environments (KASLR, SMAP, CFI)
LOW Timeline to widespread weaponization

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.

05 · Compensating Control

What to do — in priority order.

  1. Disable unprivileged user namespaces — Set kernel.unprivileged_userns_clone=0 or user.max_user_namespaces=0 via 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.
  2. Restrict /dev/net/tun access — Tighten device permissions or use a udev rule to limit /dev/net/tun to specific groups (e.g., kvm, libvirt). This reduces the attack surface for non-containerized hosts. Deploy within 30 days.
  3. 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 corresponding sudo/su. These provide detection-in-depth while patching progresses.
  4. 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.
What doesn't work
  • 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.
06 · Verification

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.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/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
fi
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: run the verification script across your Linux fleet to identify unpatched hosts. Prioritize Kubernetes nodes, KVM hypervisors, and CI runners — these are where TUN/TAP is most active and the blast radius is greatest. As an immediate compensating control, disable unprivileged user namespaces (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

  1. SecurityOnline — Linux Kernel LPE Quartet Disclosed
  2. Ubuntu Security — CVE-2026-81000
  3. GBHackers — Linux Kernel Hit by 4 LPE Flaws
  4. Vulners — CVE-2026-81000
  5. OpenCVE — CVE-2026-81000
  6. OSV — CVE-2026-81000
  7. Strix AI — CVE-2026-81000 Fix & Details
  8. OffSeq Threat Radar — CVE-2026-81000
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.