Kernel Security Linux Kernel May 2026

DirtyDecrypt / DirtyCBC — Root via rxgk_decrypt_skb

Deep analysis of LPE vulnerability CVE-2026-31635 in the Linux kernel's rxgk module. Exploiting a missing COW guard to overwrite page cache contents and achieve full root privilege escalation without race conditions or special capabilities.

CVE-2026-31635LPELinux KernelrxgkPage CacheDirty PipeCOWFedoraArch

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.

Severity: High
Public PoC available, no special privileges required, no race condition needed. Exploitation can be performed by any unprivileged user on an affected system.

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.

ConceptPage Cache — Simplified Model
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 the SKBFL_SHARED_FRAG check. 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

Cnet/rxrpc/rxgk.c (pre-patch)
/* 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

Cnet/rxrpc/rxgk.c (patch CVE-2026-31635)
/* 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

[Step 1] Prepare the environment │ Attacker calls: add_key("rxrpc", ...) │ Attacker calls: socket(AF_RXRPC, ...) │ → Module rxgk is auto-loaded into the kernel │ No root requiredNo CAP_NET_ADMIN required[Step 2] Pin page cache into pipe │ Use vmsplice() + splice() │ → Create an sk_buff whose data fragment │ points directly into the page cache of │ the target file (e.g. /usr/bin/su) │ → sk_buff frag → page cache page[Step 3] Trigger in-place decryption │ Send a packet through the RxGK socket │ → rxgk_decrypt_skb() skips the COW guard │ → Decrypts directly into the shared frag │ → OVERWRITES /usr/bin/su contents in memory[Step 4] Execute payload via SUID │ Any subsequent process calling /usr/bin/su │ will execute the modified binary │ Since su has the SUID bit set │ → Attacker gains a root shell[Step 5] Full root access │ Page cache modification is RAM-only │ → Nothing written to disk │ → FIM tools (AIDE, Tripwire) CANNOT detect │ → ★ ROOT ★
No Race Condition Required
This is a deterministic logic bug — the exploit succeeds with near-100% reliability, independent of timing or CPU scheduling. Unlike traditional race-condition LPEs that require thousands of attempts, DirtyDecrypt works every single time.

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

DistributionStatus
FedoraConfirmed — PoC tested successfully. Follows upstream kernel closely.
Arch LinuxConfirmed — Rolling release, typically runs latest mainline kernel.
openSUSE TumbleweedConfirmed — Rolling release tracking upstream.
Ubuntu / RHEL / DebianUnconfirmed — Typically use custom kernels; CONFIG_RXGK often disabled. Verify manually.

Check Your System

BashVerify kernel config
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.

VulnerabilityCVEStatus
Copy FailCVE-2026-31431Exploited in the wild. CISA added to KEV on 01/05/2026. Federal agencies ordered to patch by 15/05.
Dirty FragCVE-2026-43284 + CVE-2026-43500Chained via esp4/esp6 and rxrpc. No user namespace needed. Actively exploited.
FragnesiaCVE-2026-46300Dirty Frag variant via esp/xfrm. Public PoC available.
DirtyDecryptCVE-2026-31635Via rxgk_decrypt_skb. Public PoC available. No known in-the-wild exploitation yet.
Systemic Bug Class
These are not isolated, random bugs — they represent a systemic bug class in how the Linux kernel handles in-place decryption on paged socket buffers. It is highly likely that additional variants remain undiscovered.

07 · Disclosure Timeline

DateEvent
April 25, 2026Kernel patch for CVE-2026-31635 silently merged into mainline.
May 9, 2026V12 Security Team independently discovers the vulnerability, reports to kernel maintainers → informed it is a duplicate of an already-patched issue.
May 18, 2026V12 publicly discloses with PoC exploit (poc.c). BleepingComputer covers the story.
PresentPatch available. No confirmed in-the-wild exploitation. Immediate action recommended.

08 · Remediation & Mitigation

Priority #1 — Update Kernel Immediately

BashKernel update commands by distro
sudo dnf update kernel    # Fedora
sudo pacman -Syu          # Arch Linux
sudo zypper update kernel # openSUSE

Temporary Mitigation (Breaks IPsec VPN and AFS)

Warning
The mitigation below will break IPsec and AFS connectivity. Only apply if these services are not in use on the affected system.
BashBlacklist vulnerable modules
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"
Important Note
If the system may have been compromised before applying the mitigation, blacklisting the module is not sufficient — the page cache is already corrupted and will only reset after a full reboot or 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:

  1. No race condition — this is a deterministic logic bug. Reliability is near 100%, with no dependency on timing or CPU scheduling.
  2. No user namespace or special capabilities required — any unprivileged user can call add_key() and socket() to load the rxgk module.
  3. Public exploit available — the PoC lowers the technical barrier for any attacker.
  4. Minimal forensic footprint — modifications exist only in RAM. Nothing is written to disk, making FIM-based detection ineffective.

Realistic Attack Scenario

Phase 1 Initial Access │ Attacker obtains low-privilege shell │ (phishing, supply chain, compromised service...) │ Phase 2 Privilege Escalation │ Run DirtyDecrypt PoC │ → Root in secondsPhase 3 Post-Exploitation │ Lateral movement via SSH keys, credentials │ Persistent backdoor (cron, systemd, kernel module) │ Data exfiltration │ Outcome Full system compromise Forensic footprint: minimal FIM detection: NONE
Red Team Advisory
Although DirtyDecrypt has not yet been observed in-the-wild, Copy Fail (same bug class) is actively exploited. Attackers routinely repurpose techniques across the same vulnerability class — the time from public PoC to in-the-wild exploitation can be measured in weeks.

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

  1. Check CONFIG_RXGK — run grep CONFIG_RXGK /boot/config-$(uname -r) on all Linux systems
  2. Update kernel immediately — the patch is available in mainline and most distribution kernels
  3. Monitor distro advisories — Fedora, Arch, and openSUSE have released patched kernels
  4. Consider blacklisting the module — if AFS/IPsec is not in use, disable rxrpc, esp4, and esp6 via modprobe blacklist
Forward-Looking Guidance
The page cache write-primitive class (Dirty Pipe → Copy Fail → Dirty Frag → DirtyDecrypt) represents an ongoing research frontier. The way the Linux kernel handles in-place decryption on paged socket buffers still contains blind spots. Organizations should closely track new CVEs in this bug class and consider deploying deeper defenses such as kernel lockdown mode, signed kernel modules, and a trusted boot chain to mitigate the risk from future variants.