← blog

May 22, 2026

dirty frag field notes

Notes on Dirty Frag, AF_ALG blocking, and nscd cache weirdness.

CVEs: CVE-2026-43284 (xfrm-ESP), CVE-2026-43500 (RxRPC)
Exploit: V4bel/dirtyfrag / PR #70
Patch: aa54b1d27fe0 (RxRPC), f4c50a4034e6 (ESP), merged May 8-10, 2026

Context

These are notes from getting Dirty Frag's RxRPC path working on an Ubuntu 24.04 box where af_alg was blocked and nscd was active.

Dirty Frag gets local privilege escalation through page cache corruption. The RxRPC variant corrupts /etc/passwd line 1 to clear root's password field, then runs su against a PAM stack where pam_unix.so nullok accepts the empty password.

The annoying part was not the page cache primitive. It was the checksum path. Dirty Frag's checksum code (compute_csum_iv, compute_cksum) used the kernel crypto API directly:

c
socket(AF_ALG) + bind("skcipher", "pcbc(fcrypt)") + setkey(K)

So the key search was already userspace, but the final checksum still depended on AF_ALG. If the machine had install af_alg /bin/false in modprobe config, the exploit died before it reached the useful part.

1. nscd makes the su step look broken

On Ubuntu 24.04, nscd is active in the default setup I hit, and it can keep serving the original passwd entry after the page-cache corruption has happened. The file view is dirty, but PAM may still see the cached root:x:0:0:... entry, decide root has a real shadow hash, and reject the blank password.

The fix is just to invalidate the passwd cache after the splice wins and before launching su:

bash
systemctl is-active --quiet nscd && nscd --invalidate passwd

Without this, the exploit can look like the corruption failed even when /etc/passwd is already showing the modified root line.

2. pcbc(fcrypt) can be done without AF_ALG

A lot of mitigation snippets for Copy Fail and Dirty Frag include this:

conf
install af_alg /bin/false

That blocks the kernel crypto API path, but it does not remove the vulnerable RxRPC/ESP code paths. For Dirty Frag, it mainly broke checksum generation.

The repo already had userspace fcrypt code for the brute-force search (fcrypt_user_setkey, fcrypt_user_decrypt, and the s-box tables), so I added the missing pieces:

  1. fcrypt_user_encrypt()
  2. pcbc_fcrypt_encrypt_userspace()
  3. fallback logic in compute_csum_iv() / compute_cksum(): try AF_ALG first, then use the userspace implementation

That makes the checksum path work on AF_ALG-blocked systems.

The round-order bug

This was the easy place to get a convincing but wrong implementation.

The kernel macro is shaped like F_ENCRYPT(R_, L_, sched_): it updates the second argument using the first. The decrypt path starts with F_ENCRYPT(L, R, ...); the encrypt path starts with F_ENCRYPT(R, L, ...).

If you copy the decrypt ordering into encrypt, it compiles and runs, but the output is wrong. The fix was swapping the L/R position for the encrypt round pairs.

3. Upstream PR

The changes are in V4bel/dirtyfrag#70:

  • invalidate nscd passwd cache before su
  • add userspace fcrypt encrypt + PCBC mode
  • fall back from AF_ALG to userspace checksum generation

Mitigation

The real fix is to run a kernel with the upstream patches:

  • f4c50a4034e6 for ESP
  • aa54b1d27fe0 for RxRPC

Those landed in mainline around May 8-10, 2026. Whether a distro kernel has them is package/backport-dependent, so check your vendor kernel changelog instead of assuming based only on the build date.

If patching is not immediate, block the protocol modules Dirty Frag needs:

bash
printf 'install esp4 /bin/false
install esp6 /bin/false
install rxrpc /bin/false
' > /etc/modprobe.d/dirtyfrag.conf
rmmod esp4 esp6 rxrpc 2>/dev/null
sync && echo 3 > /proc/sys/vm/drop_caches

Blocking only af_alg is not enough. It breaks one checksum implementation, not the vulnerable kernel paths.