01 · Executive Summary
DirtyDecrypt (alias: DirtyCBC) is a Local Privilege Escalation (LPE) vulnerability in the rxgk module of the Linux kernel. An attacker running with regular user privileges can exploit this flaw to achieve full root access, taking complete control of the affected system.
The vulnerability was silently patched on April 25, 2026 (CVE-2026-31635), but the V12 Security research team independently discovered it and publicly disclosed it alongside a proof-of-concept exploit in May 2026, triggering a race between patchers and attackers across the ecosystem.
02 · Technical Background — Page Cache
To understand DirtyDecrypt, one must first grasp the Linux page cache: the kernel stores copies of on-disk files (including sensitive ones like /etc/passwd and /usr/bin/su) in RAM to improve performance. These cached copies are read-only for unprivileged users — this is a fundamental security invariant.
The entire Dirty* family of vulnerabilities (Dirty Pipe, Copy Fail, Dirty Frag, DirtyDecrypt) exploits the same core principle: tricking the kernel into writing to page cache without requiring write permissions on the actual file, thereby modifying sensitive file contents purely in memory.
User Process (unprivileged)
│ read("/usr/bin/su")
▼
┌──────────────────────────────┐
│ Page Cache (RAM) │ ← In-memory copy of file
│ /usr/bin/su [read-only] │ ← Regular user CANNOT write
│ /etc/passwd [read-only] │
└──────────────────────────────┘
│ ▲
▼ │ write() — DENIED without file permissions
Disk │
│
╔════════════╧════════════╗
║ Dirty* Vulnerability ║
║ → OVERWRITE page cache ║
║ WITHOUT write perms ║
╚═════════════════════════╝
03 · Root Cause — Missing COW Guard
The bug resides in the rxgk_decrypt_skb() function of the rxgk kernel module (RxGK — the security layer for the AFS client). When the kernel receives a packet through a socket, it needs to decrypt the data. This process has two possible paths:
- Safe path (with COW): The kernel checks whether the socket buffer (skb) points into page cache. If it does, it calls
skb_cow_data()to create a private copy, then decrypts into that copy — leaving the original page cache untouched. - Vulnerable path (missing COW guard): The
rxgk_decrypt_skb()function lacks theSKBFL_SHARED_FRAGcheck. As a result, it decrypts in-place directly into the page that points into page cache — overwriting the cached file contents without any permission check.
Vulnerable Code
/* Simplified vulnerable state */
static int rxgk_decrypt_skb(struct rxrpc_call *call, struct sk_buff *skb)
{
/* MISSING CHECK: if (skb->data_len > 0 &&
skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG)
return skb_cow_data(skb, 0, &trailer); */
/* In-place decryption — may write directly into page cache! */
crypto_skcipher_decrypt(req); /* ← DANGER POINT */
}
Patched Code
/* After patch (CVE-2026-31635) */
static int rxgk_decrypt_skb(struct rxrpc_call *call, struct sk_buff *skb)
{
/* Check for shared frags before decrypting */
if (skb->data_len > 0) {
err = skb_cow_data(skb, 0, &trailer);
if (err < 0)
goto error;
}
crypto_skcipher_decrypt(req); /* ← Now safe */
}
The difference is merely a few lines of code — but the consequence is that the entire page cache can be overwritten by an unprivileged user.
04 · Exploitation Chain — Step by Step
05 · Exploitation Conditions & Attack Surface
The kernel must have CONFIG_RXGK=y or =m enabled. This option enables the rxgk module providing RxGK security support for the AFS client — typically only enabled in distributions that closely follow upstream kernel configs.
Confirmed Affected Distributions
| Distribution | Status |
|---|---|
| Fedora | Confirmed — PoC tested successfully. Follows upstream kernel closely. |
| Arch Linux | Confirmed — Rolling release, typically runs latest mainline kernel. |
| openSUSE Tumbleweed | Confirmed — Rolling release tracking upstream. |
| Ubuntu / RHEL / Debian | Unconfirmed — Typically use custom kernels; CONFIG_RXGK often disabled. Verify manually. |
Check Your System
grep CONFIG_RXGK /boot/config-$(uname -r)
# If output shows "CONFIG_RXGK=y" or "CONFIG_RXGK=m" → VULNERABLE
# If no output or "CONFIG_RXGK=n" → NOT AFFECTED
06 · The Page Cache Vulnerability Family — Full Picture
DirtyDecrypt does not exist in isolation. It belongs to a family of page cache write-primitive vulnerabilities discovered throughout early 2026, all sharing the same underlying mechanism: tricking the kernel into writing to page cache without proper authorization.
| Vulnerability | CVE | Status |
|---|---|---|
| Copy Fail | CVE-2026-31431 | Exploited in the wild. CISA added to KEV on 01/05/2026. Federal agencies ordered to patch by 15/05. |
| Dirty Frag | CVE-2026-43284 + CVE-2026-43500 | Chained via esp4/esp6 and rxrpc. No user namespace needed. Actively exploited. |
| Fragnesia | CVE-2026-46300 | Dirty Frag variant via esp/xfrm. Public PoC available. |
| DirtyDecrypt | CVE-2026-31635 | Via rxgk_decrypt_skb. Public PoC available. No known in-the-wild exploitation yet. |
07 · Disclosure Timeline
| Date | Event |
|---|---|
| April 25, 2026 | Kernel patch for CVE-2026-31635 silently merged into mainline. |
| May 9, 2026 | V12 Security Team independently discovers the vulnerability, reports to kernel maintainers → informed it is a duplicate of an already-patched issue. |
| May 18, 2026 | V12 publicly discloses with PoC exploit (poc.c). BleepingComputer covers the story. |
| Present | Patch available. No confirmed in-the-wild exploitation. Immediate action recommended. |
08 · Remediation & Mitigation
Priority #1 — Update Kernel Immediately
sudo dnf update kernel # Fedora
sudo pacman -Syu # Arch Linux
sudo zypper update kernel # openSUSE
Temporary Mitigation (Breaks IPsec VPN and AFS)
sh -c "printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' \
> /etc/modprobe.d/dirtyfrag.conf; \
rmmod esp4 esp6 rxrpc 2>/dev/null; \
echo 3 > /proc/sys/vm/drop_caches; true"
drop_caches. File Integrity Monitoring tools like AIDE and Tripwire cannot detect in-memory modifications.
Post-Patch Verification
After updating the kernel, reboot the system to clear any potentially corrupted page cache entries. Alternatively, run echo 3 > /proc/sys/vm/drop_caches to flush the cache before rebooting. Verify the module is properly patched by checking the kernel version matches the fixed release.
09 · Red Team Perspective
From an attacker's standpoint, DirtyDecrypt is ideal for four key reasons:
- No race condition — this is a deterministic logic bug. Reliability is near 100%, with no dependency on timing or CPU scheduling.
- No user namespace or special capabilities required — any unprivileged user can call
add_key()andsocket()to load the rxgk module. - Public exploit available — the PoC lowers the technical barrier for any attacker.
- Minimal forensic footprint — modifications exist only in RAM. Nothing is written to disk, making FIM-based detection ineffective.
Realistic Attack Scenario
10 · Conclusion & Recommendations
DirtyDecrypt is a stark reminder that the Linux kernel still harbors unexplored vulnerability classes. This flaw is particularly dangerous because:
- It requires no special conditions — only the rxgk module needs to be enabled
- Exploitation is deterministic, with no timing dependencies
- Forensic footprint is minimal — modifications exist only in RAM
- It belongs to a broader bug class — additional variants likely remain undiscovered
Priority Actions
- Check CONFIG_RXGK — run
grep CONFIG_RXGK /boot/config-$(uname -r)on all Linux systems - Update kernel immediately — the patch is available in mainline and most distribution kernels
- Monitor distro advisories — Fedora, Arch, and openSUSE have released patched kernels
- Consider blacklisting the module — if AFS/IPsec is not in use, disable
rxrpc,esp4, andesp6via modprobe blacklist