Like a hotel safe that forgets it changed the combination, letting anyone with a room key rewrite what is inside every vault on the floor
CVE-2026-46300, nicknamed Fragnesia, is a logic flaw in the Linux kernel's skb_try_coalesce() path. When TCP receive coalescing moves paged fragments between socket buffers, the SKBFL_SHARED_FRAG marker is dropped. ESP input then sees skb_has_shared_frag() as false on the merged buffer, decides the nonlinear skb can skip skb_cow_data(), and decrypts in place directly over page-cache-backed fragments. An unprivileged local attacker exploits this by creating user and network namespaces to gain CAP_NET_ADMIN, installing an AES-128-GCM transport-mode ESP security association over TCP, splicing a target read-only file's pages into the receive queue, and then enabling the espintcp ULP. The kernel treats the queued file pages as ESP ciphertext and XORs its keystream into the cached pages — one byte at a time with a precomputed nonce-to-byte lookup table — overwriting the page-cache copy of any file, including setuid-root binaries like /usr/bin/su. The flaw was introduced in kernel 3.9 (2013) and affects every unpatched branch including stable series 5.10, 5.15, 6.1, 6.6, 6.12, and mainline 7.x. Fixed upstream in 5.10.257, 5.15.208, 6.1.174, 6.6.141, and 6.12.90. Discoverer: William Bowling (Zellic / V12 Security), disclosed May 13, 2026 without prior vendor coordination.
The vendor CVSS score of 7.8 HIGH (AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) is reasonable as a base measurement but undersells the operational risk. The 7.8 correctly captures the local-access prerequisite and the full CIA impact. What it fails to account for is the *reliability* of the primitive (deterministic, no race, byte-at-a-time writes), the *breadth* of the attack surface (every Linux kernel for 13 years), the *weaponization state* (Metasploit module shipping, multiple public PoCs, KEV-listed), and the *deployment-role blast radius* (container hosts, hypervisors, CI runners, database tiers — where local root means fleet-scale or supply-chain-scale impact). noisgate upgrades this to 8.2 HIGH to reflect the exploitation reality while respecting the local-access gate that prevents CRITICAL.
Bottom line: Under the noisgate mitigation SLA, HIGH severity mandates compensating controls within 30 days and full remediation (vendor patch) within 180 days. However, because this CVE is KEV-listed with active exploitation, the mitigation SLA is overridden: deploy the ESP module blacklist or namespace restriction immediately, within hours, then schedule kernel patching within your standard change window. For RHEL, Debian, Ubuntu, SUSE, and Amazon Linux, patched kernels are already available. If you run IPsec VPNs, prefer the namespace restriction (Option 1) to avoid breaking tunnels. Verify every host with the detection script below — the exploit leaves no on-disk artifacts, so sha256sum /usr/bin/su before and after a page-cache drop is your only post-exploitation indicator.
5 steps from start to impact.
Local shell on target host
- Unprivileged local shell access on a Linux host running kernel 3.9 through unpatched 7.x
- Requires a separate initial-access vulnerability or credential compromise
- Not remotely exploitable on its own — cannot target hosts without a prior foothold
unshare calls immediately following initial accessNamespace creation for CAP_NET_ADMIN
unshare(CLONE_NEWUSER | CLONE_NEWNET) to create new user and network namespaces. Inside the new network namespace, the attacker's unprivileged UID is mapped to root and gains CAP_NET_ADMIN, which is required to install XFRM security associations. This requires unprivileged user namespaces to be enabled, which is the default on Debian, Ubuntu, Fedora, RHEL 8+, and SUSE.- Unprivileged user namespaces enabled (
user.max_user_namespaces > 0anduser.max_net_namespaces > 0) - The
esp4oresp6kernel module must be loadable or already loaded
- Hardened hosts that set
user.max_user_namespaces=0oruser.max_net_namespaces=0block this step entirely - Container runtimes with restricted seccomp profiles may block
unsharewithCLONE_NEWNET
unshare syscall (-a always,exit -F arch=b64 -S unshare); Falco rule for namespace creation by non-root usersESP-in-TCP security association setup
NETLINK_XFRM to install a transport-mode ESP security association with AES-128-GCM and a known key (SPI 0x100). The attacker then precomputes a 256-entry lookup table mapping each desired output byte to the IV nonce that produces the correct keystream XOR. This setup is entirely within the attacker's namespace and does not touch the host network.- CAP_NET_ADMIN in the network namespace (achieved in step 2)
- Kernel ESP module loaded or auto-loadable
- If
esp4andesp6are blacklisted via modprobe.d, the module cannot load and this step fails - No network traffic or firewall evasion is needed — this is purely local kernel state manipulation
modprobe esp4 / esp6) logged by auditd or module loading monitors; Metasploit module IOC: writable directory artifact in /tmpSplice file pages and trigger in-place decryption
/usr/bin/su) into a TCP socket's receive queue using splice(). Before the ESP ULP is installed, these file-backed pages sit in the receive buffer as plain data. The attacker then calls setsockopt(TCP_ULP, espintcp), which causes the kernel to treat the buffered pages as ESP ciphertext and decrypt them in place. Because skb_try_coalesce() dropped the SKBFL_SHARED_FRAG marker, skb_has_shared_frag() returns false, and the kernel skips skb_cow_data() — writing the AES-GCM keystream XOR directly into the page-cache pages. This is the core vulnerability. The attacker repeats this one byte at a time, selecting the nonce from the precomputed table to produce the exact desired byte value at each offset.- The target file must be in the page cache (reading it once is sufficient)
- The kernel must not have the patch that propagates
SKBFL_SHARED_FRAGduring coalescing
- The write is deterministic and requires no race condition — there is no timing window to disrupt
- Each byte requires a separate splice-and-decrypt cycle, but the Metasploit module and PoCs automate this fully
splice, setsockopt) with no anomalous signaturesExecute corrupted setuid binary for root shell
/usr/bin/su in the page cache with a small ELF stub that calls setresuid(0,0,0) / setresgid(0,0,0) and execve(/bin/sh), the attacker simply runs /usr/bin/su. The kernel loads the corrupted page-cache copy (not the on-disk original), and the setuid bit grants root. The on-disk file is untouched — only the cached copy is modified. A reboot or echo 1 > /proc/sys/vm/drop_caches clears the corruption.- A setuid-root binary must exist (virtually universal:
/usr/bin/su,/usr/bin/passwd, etc.)
- Minimal — setuid binaries are present on every standard Linux installation
- The page-cache-only nature means forensic tools examining disk will see the original clean binary
sha256sum /usr/bin/su before and after sysctl vm.drop_caches=1; a mismatch indicates page-cache tampering. Metasploit module leaves artifacts in writable directory (default /tmp)/etc/modprobe.d/dirtyfrag.conf with install esp4 /bin/false, install esp6 /bin/false, install rxrpc /bin/false, then reboot or rmmod the modules. This breaks the exploit at step 3 of the attack path — without the ESP module, the attacker cannot install the XFRM security association that triggers in-place decryption. Also covers the related DirtyFrag (CVE-2026-43284) and Copy Fail (CVE-2026-43500) chains. Warning: This breaks kernel-mode IPsec (strongSwan, libreswan) and AFS network filesystems. Under the noisgate mitigation SLA for HIGH, deploy within 30 days — but given KEV listing, deploy within hours.user.max_net_namespaces=0 in /etc/sysctl.d/dirtyfrag.conf and run sysctl --system. This blocks step 2 of the attack path — the attacker cannot create the network namespace needed to gain CAP_NET_ADMIN. This is the preferred mitigation on hosts running IPsec VPNs because it does not unload ESP modules. Warning: Breaks rootless Podman, rootless Docker, slirp4netns, Flatpak, and browser sandboxes (Chromium, Firefox). Under the noisgate mitigation SLA for HIGH, deploy within 30 days — but given KEV listing, deploy within hours.unshare with CLONE_NEWNET and CLONE_NEWUSER. This prevents step 2 from inside containers specifically, limiting the blast radius on Kubernetes nodes and container hosts. The default Docker seccomp profile already blocks unshare; Kubernetes requires explicit securityContext.seccompProfile configuration. This does not protect bare-metal or VM workloads.- SELinux / AppArmor in default policy — The exploit uses only legitimate syscalls (
splice,setsockopt,unshare) that are permitted under standard confined profiles. Mandatory access controls do not prevent the page-cache write because it occurs inside the kernel's own ESP decryption path, not through a file-write syscall. - Network firewalls and WAFs — Fragnesia is a purely local exploit. No network traffic leaves the host. Perimeter controls, IDS/IPS, and network segmentation have zero effect on the attack chain.
- File integrity monitoring (FIM) on disk — The exploit modifies only the *page-cache copy* of the target file. The on-disk binary remains untouched. Tools like AIDE, Tripwire, or OSSEC that check disk hashes will not detect the corruption. Only comparing the in-memory hash before and after a page-cache drop reveals tampering.
The supporting signals.
| In-the-wild exploitation | KEV-listed (per user-provided intel). Qualys ThreatPROTECT advisory titles it *exploited in attacks*. The related DirtyFrag family (CVE-2026-43284, CVE-2026-43500) has confirmed exploitation; Fragnesia shares the same attack surface and mitigations. |
|---|---|
| Proof-of-concept availability | Multiple public PoCs and a Metasploit module. Primary PoC by William Bowling at v12-security/pocs/fragnesia. Go-based LPE exploit at 1neptune/Fragnesia on GitHub. Metasploit module linux/local/cve_2026_46300_fragnesia shipped in Metasploit 5.1.0-2026073001 (PR #21456 by msutovsky-r7). Mitigation checker at AzDevops143 repo. French-language writeup by Maxime288/Fragnesia-CVE-2026-46300. Telegram RedTeam channels track multiple forks. |
| EPSS score | 0.10192 (~95th percentile). This places Fragnesia in the top 5% of all CVEs by predicted exploitation probability, consistent with KEV listing and public weaponization. |
| KEV status | Listed per user-provided intelligence. CISA Known Exploited Vulnerabilities catalog. Federal agencies subject to BOD 22-01 binding remediation deadline. |
| CVSS vector | CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H (7.8 HIGH). Local attack vector, low complexity, low privileges required, no user interaction. The AV:L is the sole friction element — everything else is maximally severe. The S:U (Unchanged scope) is debatable given page-cache writes can affect any file on the system. |
| Affected versions | All Linux kernels from 3.9 (commit cef401de7be8, 2013) through unpatched mainline. Every distribution shipping a kernel in the 3.9–7.x range without the coalescing fix is vulnerable. This includes RHEL 7/8/9, Debian bullseye/bookworm/trixie, Ubuntu 18.04–26.04, SUSE 12/15, Amazon Linux 2/2023, Fedora, Arch, Alpine, and embedded Linux (Siemens SIMATIC S7-1500 MFP per OT advisory). |
| Fixed versions | Upstream stable: 5.10.257, 5.15.208, 6.1.174, 6.6.141, 6.12.90, 7.0.6. Debian: bullseye 5.10.257-1 (DLA-4606-1), bookworm 6.1.174-1 (DSA-6306-1), trixie 6.12.90-1 (DSA-6295-1). Azure Linux: 6.6.141.1-1. Rocky/CIQ: vendor-specific backports for 4.18 and 5.14 branches (see CIQ advisory). Fedora 43: kernel 7.0.6. |
| Discoverer | William Bowling, head of assurance at Zellic, publishing as V12 Security (v12-security on GitHub). Disclosed May 13, 2026 on the netdev mailing list without prior coordination with kernel maintainers or distribution security teams. Upstream commit: f84eca58. |
| Disclosure timeline | 2026-05-13: Public disclosure, PoC release, and netdev patch posting (v1). 2026-05-14: BleepingComputer coverage. 2026-05-15: CIQ/Rocky Linux and Qualys advisories. Distribution patches began rolling out same week. 2026-05-21: Picus Security deep-dive published. Metasploit module landed in the 2026-07-30 release. |
| Related vulnerabilities | Part of the DirtyFrag family: CVE-2026-43284 (Dirty Frag, xfrm-ESP page-cache write), CVE-2026-43500 (Copy Fail 2, RxRPC path), CVE-2026-43503 (DirtyClone). All share the ESP/XFRM attack surface and the same esp4/esp6/rxrpc module blacklist mitigation. Fragnesia exploits a *different code path* (skb_try_coalesce) from the original DirtyFrag (__pskb_copy_fclone), so the original DirtyFrag patch alone does NOT fix Fragnesia. |
Sources.
- Debian Security Tracker — CVE-2026-46300
- Picus Security — Fragnesia CVE-2026-46300 Explained
- BleepingComputer — Fragnesia Linux Flaw
- Qualys ThreatPROTECT — CVE-2026-46300
- CIQ — Fragnesia Mitigation on Rocky Linux
- Kernel upstream fix commit
- Rapid7 Metasploit Module
- Rapid7 Release Notes — Metasploit 5.1.0-2026073001
Why this verdict
- KEV-listed and fully weaponized: CISA KEV inclusion confirms real-world exploitation. A shipping Metasploit module (
linux/local/cve_2026_46300_fragnesia) eliminates any skill barrier. EPSS of 0.102 (~95th percentile) independently corroborates active threat. This is not a theoretical bug — it is being used in intrusions today. - Deterministic, race-free kernel primitive: Unlike the majority of kernel LPEs that depend on race windows, Fragnesia provides controlled byte-at-a-time page-cache writes with zero timing dependency. The attacker selects a precomputed AES-GCM nonce to produce any desired byte at any offset. This reliability elevates the chain significantly above typical kernel memory-corruption bugs and renders common defenses like SMAP/SMEP/KASLR irrelevant.
- Universal attack surface, minimal prerequisites: Every Linux kernel since 3.9 (13 years) is affected. The sole non-trivial prerequisite — unprivileged user-namespace creation — is enabled by default on Debian, Ubuntu, Fedora, RHEL 8+, SUSE, Amazon Linux, and Alpine. No kernel config flags, no installed packages, no hardware features. On a default install, any UID can reach the vulnerable code path.
- Role multiplier — the Linux kernel IS the canonical high-value component: More than 50% of Linux server installs serve in at least one high-value role: Kubernetes nodes, KVM/QEMU hypervisors, CI/CD runners (Jenkins agents, GitLab runners, GitHub Actions self-hosted), production database tiers, SIEM collectors, backup agents, and OT controllers (Siemens S7-1500 MFP confirmed affected). On container hosts, local root from Fragnesia enables container escape via
/proc/sysrq-trigger,nsenter, or cgroup manipulation — escalating from one workload to the entire node and potentially the cluster. On CI runners, root means access to pipeline secrets and the ability to inject malicious artifacts (supply-chain blast radius). On database servers, root means unrestricted data exfiltration. The chain succeeds identically on all these hosts. This sets a HIGH floor that friction alone cannot breach. - Local-access gate is real but bounded friction: The AV:L prerequisite means the attacker needs an initial shell. This is a genuine gate that prevents mass unauthenticated exploitation and is the reason this is HIGH rather than CRITICAL. However, in a post-initial-access context (which is exactly when LPEs matter), every unpatched Linux host is one automated command away from root. The friction is a single link in a chain that attackers routinely clear — it does not make the vulnerability academic.
Why not higher?
Fragnesia cannot be triggered remotely. The attacker must already hold a local shell on the target host before the chain begins. While the blast radius on high-value roles (container hosts, hypervisors, CI runners) can extend to fleet-scale or supply-chain-scale compromise, the exploitation chain is always a *second stage* — it compounds with, but does not replace, an initial-access vulnerability. In a fleet of 10,000 hosts, the realistic exposure is the subset already compromised through another vector, not the entire population simultaneously. That single prerequisite bounds the concurrency of exploitation below what a remote unauthenticated CRITICAL would produce.
Why not lower?
A deterministic, race-free kernel LPE with a shipping Metasploit module, confirmed KEV listing, and a 13-year attack surface spanning every major Linux distribution is not a theoretical risk. User namespaces — the only unusual prerequisite — are enabled by default on every enterprise-grade distribution shipped since 2018. On high-value Linux roles (container orchestrators, hypervisors, CI runners, database tiers), local root is game over: it enables container escape, VM boundary violations, pipeline poisoning, and unrestricted data access. The deployment-role blast radius analysis floors this at HIGH regardless of the local-access friction. Dropping to MEDIUM would require evidence that fewer than 1% of Linux hosts run in exploitable configurations, which contradicts default-on namespace settings across all major distributions.
Crowdsourced verification payload.
Run as root on each target Linux host: sudo bash check_cve_2026_46300.sh. Root is needed to probe module loading and sysctl values. The script checks the running kernel against known fixed stable branches, verifies ESP module blacklisting, checks namespace restrictions, and prints PATCHED, VULNERABLE, or UNKNOWN. For RHEL/CentOS with backported kernels (e.g., 4.18.x, 5.14.x), the script will print UNKNOWN — check your vendor advisory directly.
#!/usr/bin/env bash\nset -euo pipefail\n# CVE-2026-46300 (Fragnesia) vulnerability checker\n# Exit: 0=PATCHED 1=VULNERABLE 2=UNKNOWN\nR=UNKNOWN\nK=$(uname -r)\necho "Kernel: $K"\nIFS='.-' read -r A B C _ <<< "$K"\nBR=$A.$B\ncase $BR in\n 5.10) F=257;; 5.15) F=208;; 6.1) F=174;;\n 6.6) F=141;; 6.12) F=90;; 7.0) F=6;; *) F=;;\nesac\nif [ -n "$F" ]; then\n if [ "$C" -ge "$F" ] 2>/dev/null; then\n echo "[PATCHED] kernel $BR.$C >= $BR.$F"; R=PATCHED\n else\n echo "[VULN] kernel $BR.$C < $BR.$F"; R=VULNERABLE\n fi\nelse\n echo "[INFO] branch $BR not in fixed-version map -- check vendor advisory"\nfi\n# ESP module mitigation check\nEB=true\nfor m in esp4 esp6; do\n if modprobe -n -v $m 2>/dev/null | grep -q /bin/false; then\n echo "[OK] $m blacklisted"\n elif lsmod | grep -qw $m 2>/dev/null; then\n echo "[EXPOSED] $m loaded"; EB=false\n else\n echo "[OK] $m not loaded"\n fi\ndone\n# Namespace sysctl check\nUN=$(sysctl -n user.max_user_namespaces 2>/dev/null || echo '?')\nNN=$(sysctl -n user.max_net_namespaces 2>/dev/null || echo '?')\nNS=false\nif [ "$UN" = 0 ] || [ "$NN" = 0 ]; then\n echo "[OK] namespaces restricted (user=$UN net=$NN)"; NS=true\nelse\n echo "[EXPOSED] namespaces open (user=$UN net=$NN)"\nfi\n# Override vulnerable verdict if mitigations are active\nif [ "$R" = VULNERABLE ]; then\n if $EB; then echo "[MITIGATED] ESP modules blocked"; R=PATCHED; fi\n if $NS; then echo "[MITIGATED] namespaces restricted"; R=PATCHED; fi\nfi\n# Page-cache integrity spot-check\nif [ -f /usr/bin/su ] && command -v sha256sum >/dev/null 2>&1; then\n H1=$(sha256sum /usr/bin/su | awk '{print $1}')\n sysctl -w vm.drop_caches=1 >/dev/null 2>&1 || true\n H2=$(sha256sum /usr/bin/su | awk '{print $1}')\n if [ "$H1" != "$H2" ]; then\n echo "[ALERT] /usr/bin/su page-cache differs from disk -- POSSIBLE EXPLOITATION"\n R=VULNERABLE\n else\n echo "[OK] /usr/bin/su page-cache matches disk"\n fi\nfi\necho "---"\necho "$R"\ncase $R in PATCHED) exit 0;; VULNERABLE) exit 1;; *) exit 2;; esac