Fragnesia (CVE-2026-46300): check your Linux servers for tampering before you reboot them
On October 28 CISA added CVE-2026-46300, a Linux kernel bug called Fragnesia, to its Known Exploited Vulnerabilities catalog, with a due date of October 31 for federal agencies.
The bug isn’t new. The fix went to the kernel’s networking list on May 13, and Ubuntu and Red Hat shipped fixed kernels months ago. However, the exploit is now being used in the wild. On October 27, Dream reported attackers chaining it with PHP2Shell (the PHP bugs from my earlier post) to get root on about 25 servers, mostly firewall appliances, including machines on a US government-affiliated network. PHP2Shell got them a shell as the web server’s user, and this Fragnesia exploit turned that into root. Their backdoor was a changed /etc/pam.d/su that lets anyone su to root.
The backdoor only exists in memory
Fragnesia lives in the kernel’s ESP-in-TCP code (IPsec). A local user that can create a user namespace can use it to change files they’re only allowed to read, like /etc/pam.d/su or /usr/bin/sudo. It doesn’t touch the file on the disk. It changes the page cache, which is the copy of the file the kernel keeps in memory and gives to every program that opens it.
So, when the attackers rewrote /etc/pam.d/su, every program on the machine saw the rewritten version, while the disk still held the original. This has two consequences:
- A reboot erases it. Same with dropping the page cache, or memory pressure pushing the file out. The backdoor and the evidence both go away.
- Anything that reads the disk directly sees a clean file. A disk image, a backup, or the same disk mounted on another machine all show the original. Tools that read the file normally on the running machine (
rpm -V,debsums, AIDE) do see the changed version, but only until the reboot.
That’s why the order matters. The usual fix is to install the new kernel and reboot, and that reboot is exactly what destroys the evidence. Check for tampering first, then patch.
Check one machine
Run these as root, before you reboot anything.
Tampering. This compares each file’s in-memory copy (a normal read) with its disk copy (an O_DIRECT read, which bypasses the page cache). They only differ if something changed the in-memory copy without writing it to disk:
sudo bash -c 'for f in /etc/pam.d/* /etc/sudoers /etc/shadow $(find /usr/bin /usr/sbin -xdev -perm -4000 -user root -type f); do cmp -s "$f" <(dd if="$f" iflag=direct bs=1M status=none) || echo "DIFFERENT: $f"; done'
No output means nothing differs. And the specific backdoor from the report:
grep -E '^\s*auth\s+sufficient\s+pam_permit' /etc/pam.d/su /etc/pam.d/sudo /etc/pam.d/login /etc/pam.d/sshd
That should print nothing. (Debian and Ubuntu have a normal auth required pam_permit.so line in common-auth. That one’s fine; sufficient is the problem.)
If either finds something, don’t reboot. Copy the changed files with cat (that reads the in-memory version, which is the evidence), capture memory if you can, and treat the machine as rooted: rebuild it rather than clean it.
Is the running kernel fixed. Go by your distribution’s changelog, not the version number, because distributions backport the fix into their own kernels. On Ubuntu:
zgrep -c CVE-2026-46300 /usr/share/doc/linux-modules-$(uname -r)/changelog.Debian.gz
On RHEL, Rocky and Alma:
rpm -q --changelog kernel-core-$(uname -r) | grep -c CVE-2026-46300
Anything above 0 means the kernel you’re running has the fix. Both of my lab machines did (Ubuntu 26.04 on 7.0.0-38, Rocky 9.8 on 5.14.0-687.56.1). Ubuntu lists the fixed kernels as 7.0.0-22.22 for 26.04, 6.17.0-35.35 for 25.10, 6.8.0-124.124 for 24.04 and 5.15.0-181.191 for 22.04, and 20.04 and older aren’t affected. Upstream, it’s fixed in 7.0.10, 6.18.33, 6.12.91, 6.6.141, 6.1.174 and 5.15.208.
If the fixed kernel is installed but the machine hasn’t rebooted into it yet, it’s still running the old one. uname -r shows the kernel that’s actually running.
How I tested the tampering check
I couldn’t use the real exploit on my lab machine, so I made the same mismatch the other way round. I created a setuid test file, read it so it was cached, then wrote different bytes straight to its blocks on the disk device, underneath the filesystem. The page cache still held the old bytes and the disk held the new ones. Here’s RFF’s check on that Ubuntu VM:

I deleted the test file afterwards. On the same machine without it, every file matched.
If you can’t reboot yet
Red Hat’s bulletin gives two mitigations and both have a cost:
- Stop the IPsec ESP modules from loading.
install esp4 /bin/falseandinstall esp6 /bin/falsein a file under/etc/modprobe.d/, then unload them. This breaks IPsec on that machine (strongSwan, Libreswan, an IPsec VPN or tunnel). WireGuard and OpenVPN don’t use it. I tested it on Ubuntu 26.04 and Rocky 9.8:modprobe esp4was refused on both. (Test it on your own machines. Last week the same kind of block didn’t work for a different kernel module, becausemodprobeskips the line for modules with soft dependencies, and esp4 and esp6 don’t have any.) - Turn off unprivileged user namespaces (
user.max_user_namespaces=0). That breaks rootless containers, Flatpak and the sandbox in some browsers.
Ubuntu 24.04 and later already restrict what unprivileged user namespaces can do through AppArmor. I haven’t tested whether that alone stops this exploit, so I wouldn’t count on it.
Neither mitigation undoes tampering that already happened. Run the check first.
Doing this across a fleet
The RFF Script Library has two new Linux entries:
- Fragnesia (CVE-2026-46300) - Exposure Check (Linux) runs the tampering comparison on PAM files, sudoers, passwd and shadow, sshd_config,
ld.so.preloadand every setuid-root binary, looks for thepam_permitbackdoor, then judges the running kernel from the distribution’s changelog and reports whether a fixed kernel is installed but not booted, whether the ESP modules can load, whether user namespaces are open, and whether the machine uses IPsec. It never reboots or drops caches. - Block Fragnesia (CVE-2026-46300) (Linux) writes the
modprobe.dblock, unloads the modules, and then provesmodprobeis refused on that machine instead of assuming it. It refuses to run on a machine with active IPsec connections, and it has a dry run and an undo.
Here’s the block on the Rocky 9.8 VM:

If you’re running PHP on Linux, the PHP2Shell checks from the earlier post are the other half of this chain.
RFF is free for your first 100 endpoints: getrff.com.
Sources
- CISA: Known Exploited Vulnerabilities catalog, CVE-2026-46300
- Tenable: Fragnesia (CVE-2026-46300) FAQ
- HOL Guard: Fragnesia used to turn PHP2Shell web shells into root (the Dream report and the upstream fixed versions)
- Ubuntu: CVE-2026-46300
- Red Hat: CVE-2026-46300 and RHSB-2026-003 (the mitigations)
Comments
Comments use GitHub Discussions, so you'll need a GitHub account to post. Corrections are especially welcome.