Someone left a loaded gun in the IPsec janitor's closet — dangerous, but you need a badge to get inside
CVE-2026-72137 is a double-free in the Linux kernel's xfrm subsystem, specifically in nat_keepalive_send(). When the IPv4/IPv6 send helper returns an error, the function frees the skb (socket buffer) a second time — the networking stack already consumed and freed it. This creates a classic use-after-free / double-free primitive that, with careful heap grooming, yields kernel-mode code execution and root privilege escalation. The bug was introduced in commit f531d13bdfe3 (June 2024) and affects kernels from 6.11 through pre-fix. Upstream fixes landed in July 2026 and are available in stable branches 6.12.101, 6.18.40, 7.1.5, and 7.2-rc4. Red Hat Enterprise Linux 6–9 is not affected because RHEL never shipped kernel 6.11+.
The vendor (NVD) severity of CVSS 9.8 CRITICAL with AV:N is flatly wrong. This is a local privilege escalation — the attacker must already have shell access on the target host. Red Hat independently rescored it as 7.0 HIGH with vector AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H, and that assessment is far more accurate. The AC:H reflects the heap manipulation required to weaponize a double-free, and AV:L correctly captures that no network-only attack path exists. The NVD 9.8 likely resulted from automated scoring that conflated the xfrm *networking* subsystem with a network attack vector — a common error for kernel CVEs in packet-handling code.
5 steps from start to impact.
Obtain local shell access
- Local unprivileged access to the target host
- Kernel version 6.11 through pre-fix (6.12.101, 6.18.40, 7.1.5, 7.2-rc4)
- Requires prior compromise — the attacker is already post-initial-access
- RHEL 6–9 hosts are entirely unaffected, removing a large fraction of enterprise Linux
Activate xfrm NAT-T keepalive path
nat_keepalive_send(), which only executes when IPsec Security Associations with NAT traversal keepalive are active. The attacker needs this code path to fire. On hosts not running IPsec/StrongSwan/Libreswan with NAT-T, the vulnerable function is never called. An unprivileged user can create xfrm states via XFRM_MSG_NEWSA if CAP_NET_ADMIN is available in a user namespace.- xfrm/IPsec NAT-T keepalive code path must be reachable
- User namespaces enabled (default on most modern distros) OR IPsec already configured
- Most enterprise Linux hosts do not run IPsec VPN termination
- User-namespace xfrm access may be restricted by seccomp or AppArmor profiles
XFRM_MSG_NEWSA netlink messages; monitor for unexpected xfrm state creationTrigger double-free via send error
ip_build_and_send_pkt() or ip6_xmit() returns an error *after* consuming the skb. The networking stack frees the skb on the error path, then nat_keepalive_send() frees it again. This requires precise timing and network state manipulation to force the error condition while the skb has already been consumed.- Ability to influence network routing or interface state to force send errors
- Precise timing to hit the race window
- Double-free timing is non-trivial; PoC required specific Ubuntu 26.04 kernel build
- KASLR, SMEP, SMAP, and kernel hardening increase exploitation difficulty
Heap grooming and privilege escalation
cred structures or function pointers to achieve uid=0. This is the standard kernel double-free → LPE playbook.- Successful double-free primitive from step 3
- Knowledge of kernel slab layout (varies by config and version)
- CONFIG_SLAB_FREELIST_HARDENED and CONFIG_SLAB_FREELIST_RANDOM raise the bar
- PoC demonstrated on specific Ubuntu build; porting to other distros requires rework
setuid(0) from unexpected processes; kernel integrity monitoringRoot shell / post-exploitation
- Successful exploitation from steps 1–4
- Entire chain must succeed sequentially — any break stops the attack
The supporting signals.
| In-the-wild exploitation | No confirmed exploitation in the wild as of 2026-09-03. No GreyNoise or Shadowserver activity reported. Not a remotely triggerable bug, so mass scanning is not applicable. |
|---|---|
| Proof of concept | Public PoC available from NebuSec (CyberMeowfia GitHub repository). Includes video demonstration of root escalation on Ubuntu 26.04 with kernel 7.0.0-28. Significantly lowers exploitation barrier for targeted attacks. |
| EPSS | 0.00663 (0.7%, ~30-day probability). Low, reflecting the local-only attack vector and niche xfrm prerequisite. |
| KEV status | Not listed on CISA KEV catalog as of 2026-09-03. |
| CVSS vectors | NVD: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (9.8) — incorrect, AV:N is wrong. Red Hat: CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H (7.0) — accurate. |
| Affected versions | Linux kernel 6.11 through pre-fix. Introduced in commit f531d13bdfe3 (June 2024). RHEL 6–9 not affected. Primary exposure: Ubuntu 24.10+, Fedora 41+, Arch, openSUSE Tumbleweed, Debian testing/unstable. |
| Fixed versions | Upstream stable: 6.12.101, 6.18.40, 7.1.5, 7.2-rc4. Ubuntu and Fedora have shipped patched kernels. Check distro-specific advisories for backport status. |
| Scanning/exposure data | Not applicable — local-only vulnerability. No Shodan/Censys/FOFA exposure surface. Exposure is measured by kernel version inventory, not internet-facing services. |
| Disclosure date | 2026-08-15 (public disclosure). Fix committed upstream July 2026. |
| Researcher/org | NebuSec security research team. PoC published via CyberMeowfia GitHub. |
noisgate verdict.
The single most decisive factor driving the downgrade from CRITICAL to HIGH is the incorrect NVD attack vector: this is a local privilege escalation (AV:L), not a network-reachable RCE (AV:N), and Red Hat's independent rescore to 7.0 confirms this. The public PoC and kernel-level impact prevent further downgrade below HIGH.
Why this verdict
- NVD AV:N is wrong: The double-free is in
nat_keepalive_send(), a kernel-internal function. Exploitation requires local shell access. Red Hat correctly assignedAV:L. This single correction drops the CVSS from 9.8 to the 7.x range. - AC:H is justified: Weaponizing a kernel double-free requires heap grooming, KASLR bypass, and precise timing. The NebuSec PoC works on a specific Ubuntu build; porting requires non-trivial kernel internals knowledge.
- Narrow affected population: Only kernels 6.11+ are vulnerable. RHEL (the dominant enterprise distro) is entirely unaffected. Exposure is concentrated on Ubuntu 24.10+, Fedora 41+, and rolling-release distros — a minority of enterprise fleets.
- xfrm prerequisite narrows further: The vulnerable code path requires IPsec NAT-T keepalive to be active or user-namespace xfrm access. Most Linux servers do not terminate IPsec tunnels.
- Role multiplier: The Linux kernel is the affected component, and kernel LPE is universally impactful regardless of host role. On VPN gateways (StrongSwan/Libreswan hosts where xfrm is *guaranteed* to be active), the chain both succeeds more reliably AND yields network-edge control — blast radius extends to all traffic traversing the gateway. On Kubernetes nodes, root = container escape = cluster compromise. On KVM hypervisors, root = guest VM access. These high-value roles keep the floor at HIGH despite the friction. However, <10% of the installed base of affected kernels occupies these roles, and the xfrm prerequisite already aligns with VPN gateway use, so the floor does not rise to CRITICAL.
Why not higher?
CRITICAL would require either a network-reachable attack vector or a scenario where the majority of affected hosts are high-value targets. Neither applies: the bug requires local access (post-compromise), RHEL is unaffected, and the xfrm/IPsec prerequisite limits the reliably exploitable population to VPN gateways and hosts with user namespaces. No wild exploitation exists, and the PoC is tied to a single Ubuntu build.
Why not lower?
A public PoC demonstrating root escalation exists, the kernel is the most privileged software on any host, and the affected component (xfrm) is *definitionally* active on VPN gateways — meaning the hosts where this bug is most exploitable are also the highest-value targets. MEDIUM would understate the risk for any fleet running StrongSwan/Libreswan on modern kernels.
What to do — in priority order.
- Restrict user namespaces on affected hosts — Set
kernel.unprivileged_userns_clone=0(sysctl) or apply AppArmor/SELinux restrictions to block unprivileged xfrm state creation. This eliminates the most common path for an unprivileged attacker to reach the vulnerable code. Deploy within 30 days per the noisgate mitigation SLA for HIGH. - Audit and isolate IPsec-terminating hosts — Identify all hosts running StrongSwan, Libreswan, or custom IPsec with NAT-T enabled. These are the highest-risk targets. Prioritize kernel patching on these hosts first. If patching is delayed, restrict local shell access to these systems to essential administrators only.
- Enable KASAN in non-production kernels — Kernel Address Sanitizer will immediately detect and halt double-free exploitation attempts. Not suitable for production due to performance overhead, but valuable for detecting exploitation in staging/test environments.
- Monitor for anomalous xfrm netlink messages — Use auditd rules to log
XFRM_MSG_NEWSAandXFRM_MSG_NEWPOLICYfrom non-root, non-IPsec-daemon processes. Any unprivileged process creating xfrm states is suspicious and warrants investigation.
- Network firewalls / WAF / IDS — This is a local privilege escalation, not a network attack. No network-layer control can prevent exploitation once the attacker has shell access.
- RHEL patching — RHEL 6–9 does not ship the vulnerable code. Patching RHEL hosts for this CVE is a no-op; focus on Ubuntu, Fedora, and rolling-release distros.
- Container isolation alone — If user namespaces are enabled (common in rootless container setups), an attacker inside a container can potentially reach the xfrm code path. Namespace restrictions must be explicit.
Crowdsourced verification payload.
Run this script on each target Linux host as root (or with sudo). Invoke with: sudo bash check_cve_2026_72137.sh. It checks kernel version against known-fixed versions and whether xfrm NAT-T keepalive is actively in use.
#!/bin/bash
# CVE-2026-72137 Checker — xfrm nat_keepalive double-free
# Run as root on target Linux hosts
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -euo pipefail
KERNEL=$(uname -r)
VERSION=$(echo "$KERNEL" | grep -oP '^[0-9]+\.[0-9]+\.[0-9]+')
if [ -z "$VERSION" ]; then
echo "UNKNOWN — could not parse kernel version from: $KERNEL"
exit 2
fi
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3)
# Check if this is a RHEL/CentOS kernel (not affected)
if [ -f /etc/redhat-release ] && rpm -q kernel 2>/dev/null | grep -qP 'el[6-9]'; then
echo "PATCHED — RHEL/CentOS kernel detected; CVE-2026-72137 does not affect RHEL-shipped kernels."
exit 0
fi
# Vulnerable range: 6.11.0 through pre-fix
# Fixed in: 6.12.101+, 6.18.40+, 7.1.5+, 7.2+
VULNERABLE=0
if [ "$MAJOR" -lt 6 ]; then
echo "PATCHED — kernel $VERSION predates vulnerable code (introduced in 6.11)."
exit 0
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -lt 11 ]; then
echo "PATCHED — kernel $VERSION predates vulnerable code (introduced in 6.11)."
exit 0
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -eq 12 ] && [ "$PATCH" -ge 101 ]; then
echo "PATCHED — kernel $VERSION includes fix (6.12.101+)."
exit 0
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -eq 18 ] && [ "$PATCH" -ge 40 ]; then
echo "PATCHED — kernel $VERSION includes fix (6.18.40+)."
exit 0
elif [ "$MAJOR" -eq 7 ] && [ "$MINOR" -eq 1 ] && [ "$PATCH" -ge 5 ]; then
echo "PATCHED — kernel $VERSION includes fix (7.1.5+)."
exit 0
elif [ "$MAJOR" -eq 7 ] && [ "$MINOR" -ge 2 ]; then
echo "PATCHED — kernel $VERSION includes fix (7.2+)."
exit 0
elif [ "$MAJOR" -gt 7 ]; then
echo "PATCHED — kernel $VERSION is beyond affected range."
exit 0
else
VULNERABLE=1
fi
# Check if xfrm NAT-T keepalive is active (increases risk)
XFRM_ACTIVE="no"
if ip xfrm state 2>/dev/null | grep -q 'encap type espinudp'; then
XFRM_ACTIVE="yes"
fi
if [ "$VULNERABLE" -eq 1 ]; then
echo "VULNERABLE — kernel $VERSION is in the affected range (6.11 to pre-fix)."
echo " xfrm NAT-T active: $XFRM_ACTIVE"
if [ "$XFRM_ACTIVE" = "yes" ]; then
echo " WARNING: IPsec NAT-T is active — this host is at elevated risk."
fi
exit 1
fi
echo "UNKNOWN — could not determine patch status for kernel $VERSION."
exit 2If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.