Skip to main content

Why Dirty Frag Couldn't Touch Workloads Under a Tailored AppArmor Profile Either

Dirty Frag is a universal Linux kernel LPE that chains two CVEs, CVE-2026-43284 and CVE-2026-43500, explicitly designed to bypass the Copy Fail mitigation. For workloads running under a behavior-generated AppArmor profile, neither variant's required surface was ever in the allow list. Here's why, and how to confirm your exposure in seconds.

H

Hannes Ullman

bifrost security

Why Dirty Frag Couldn't Touch Workloads Under a Tailored AppArmor Profile Either

Dirty Frag is a universal Linux kernel LPE chain published on the 7th of May. It composes two page-cache write primitives, the xfrm-ESP variant (CVE-2026-43284, patched in mainline as f4c50a4034e6 and not yet in any distro) and the RxRPC variant (CVE-2026-43500, no patch in any tree). The bug class spans roughly nine years of kernels and reaches every major distribution.

The chain was built specifically to bypass the publicly known Copy Fail mitigation, the algif_aead modprobe blacklist. Mitigation by CVE is a treadmill. The next bug in this class will need its own blacklist, and the one after that. For workloads running under a bifrost-generated AppArmor profile, Dirty Frag is the same shape of non-event Copy Fail was.

Two chokepoints, not one

Dirty Frag is two exploits chained so the blind spots cover each other.

xfrm-ESP variant. Drives a 4-byte arbitrary STORE through the page cache via the kernel’s IPsec sink, then overwrites /usr/bin/su with a static ELF. Required surface:

  • unshare(CLONE_NEWUSER | CLONE_NEWNET) to obtain CAP_NET_ADMIN
  • NETLINK_XFRM to register an XFRM SA carrying the malformed XFRMA_REPLAY_ESN_VAL
  • setsockopt(SOL_UDP, UDP_ENCAP_ESPINUDP) on a UDP socket bound to :4500
  • splice() to pin the target page

RxRPC variant. Overwrites the first line of /etc/passwd so a passwordless su succeeds. Required surface:

  • socket(AF_RXRPC, ...), with rxrpc.ko loaded on the host (Ubuntu loads it by default, RHEL doesn’t ship it)
  • add_key("rxrpc", ...) to seed the session key
  • socket(AF_ALG, ...) for the cksum precomputation
  • splice() plus recvmsg() to land the write

The chain’s structural choice is what’s interesting. Where Ubuntu blocks unprivileged user namespaces, the ESP variant can’t acquire CAP_NET_ADMIN, so RxRPC carries it. Where RxRPC isn’t loaded, ESP carries it. Universal coverage by composition.

Why allow-listing keeps winning

A bifrost-generated profile only allows the network families, capabilities, and syscalls a workload actually exercised during its learning window. The trigger surfaces Dirty Frag needs are not in the observed set for normal application traffic:

  • AF_RXRPC is an AFS file-system protocol. No web app, microservice, ML pod, or message broker we’ve seen speaks it. AppArmor’s network rxrpc rule is never granted by a learned profile.
  • AF_ALG is the same kernel-crypto chokepoint Copy Fail hinged on. Same answer: not in normal app traffic, so network alg stays denied.
  • Unprivileged user namespaces are denied by the userns rule. The few containers that legitimately nest namespaces, some build runners and certain CI jobs, surface on profile review.
  • add_key and keyctl are denied by the keyring rules.
  • NETLINK_XFRM is denied unless the workload registered XFRM transforms during the learning window, which application workloads don’t.

Either variant of Dirty Frag needs at least one of these surfaces. The chain was designed to cover the modprobe-blacklist blind spot, but a default-deny profile never enumerated those modules, syscalls, or families in the first place. There’s nothing to bypass when the default answer is no.

This is the behavior allow-listing thesis playing out a second time in two weeks. You don’t need to predict tomorrow’s CVE. You need the profile to reflect what the app actually does.

Assess your exposure in seconds

In bifrost, every running workload is continuously analyzed against its allow-listed profile, and that profile is mapped against the syscall, capability, and network-family requirements of known CVEs. To check your exposure to Dirty Frag:

  1. Open the bifrost dashboard.
  2. Search for CVE-2026-43284 or CVE-2026-43500.
  3. Read the per-workload verdict.

For both CVEs, the expected output is a list of every protected workload showing not exploitable, because no profile in the cluster permits the combination of AF_RXRPC, AF_ALG, unprivileged userns, and XFRM netlink the chain depends on. Hand the view to your CISO, confirm the kernel patch can roll out at a normal cadence rather than as a fire drill, and stop carrying these CVEs as P0.

Two caveats, kept honest

This claim survives scrutiny only if it’s stated precisely.

Node-level coverage matters. Dirty Frag compromises the host. If your application pods are profiled but a sidecar, an unconfined DaemonSet, a node agent, or a CI runner on the same node lacks a profile, the kernel is reachable from that other process. The resulting root compromise affects every pod on the node, including the profiled ones. The strongest version of the claim is this: Dirty Frag is unreachable for any workload running under a bifrost-generated profile, and if you cover the cluster comprehensively, it’s unreachable cluster-wide.

Some workloads legitimately need IPsec. A handful of service-mesh implementations and CNI plugins encrypt node-to-node traffic via IPsec, which requires XFRM netlink and network udp to :4500. Those workloads need the host kernel patched. AppArmor cannot help. RxRPC, by contrast, is essentially never a legitimate need for a containerized workload.

The takeaway

Dirty Frag’s whole structural argument is that mitigation by enumeration of bad doesn’t scale. The Copy Fail mitigation didn’t catch it. The next bug in this class won’t be caught by the Dirty Frag mitigation. Each new variant forces a new blacklist, a new patch, a new fire drill.

Allow-listing doesn’t move. It enumerates good. The good list never included AF_RXRPC, unprivileged userns, or AF_ALG, and it won’t include the next thing either. That’s the case for tailored profiles, made twice in a row by the same bug class. There will be a third one, and it will land the same way.

Tags

apparmor container security kubernetes cve runtime

Ready to see runtime security in action?

bifrost automatically generates tailored security profiles for your containers and cuts CVE noise by up to 90%. Free trial, no credit card required.