On June 17, 2026, a public exploit nicknamed packet_edit_meme demonstrated how an unprivileged user could rewrite the kernel's cached copy of /bin/su and walk away with a root shell — through the packet header editor in Linux traffic control, a QoS feature most platform teams have never once audited for security bugs. No race to win, no kernel offsets to guess, no compiled payload: configure a tc pedit rule from inside an unprivileged network namespace and the kernel corrupts its own page cache for you.
With this bug — CVE-2026-46331, "pedit COW" — this running tracker reaches five independent Linux kernel escapes disclosed inside a single ten-week window. Here is the full accounting, ordered by disclosure date:
| # | Escape | CVE | Subsystem | Primitive | Disclosed |
|---|---|---|---|---|---|
| 1 | CopyFail | CVE-2026-31431 | crypto (AF_ALG / algif_aead) | 4-byte page-cache write, no race; 732-byte Python PoC | Apr 29, 2026 |
| 2 | ITScape | CVE-2026-46316 | KVM/arm64 (GICv3 ITS emulation) | virtual-interrupt-controller race to guest-to-host escape | Jun 10, 2026 |
| 3 | pedit COW | CVE-2026-46331 | net/sched (act_pedit) | partial-COW page-cache write via tc rule | Jun 17, 2026 |
| 4 | GhostLock | CVE-2026-43499 | futex (rtmutex priority inheritance) | use-after-free to root and container escape, no privileges needed | Jul 7, 2026 |
| 5 | Januscape | CVE-2026-53359 | KVM/x86 (shadow MMU) | use-after-free to guest-to-host escape on Intel and AMD | Jul 7, 2026 |
April 29 to early July is roughly ten weeks. Five escapes, five subsystems, one shared lesson about how much kernel surface a self-hosted fleet is actually standing on. (Depending on how you count near-contemporaries like Dirty Frag and DirtyClone, the true number is even higher — which only sharpens the point.)
How pedit COW works in 200 words
Linux traffic control (tc) includes an action called act_pedit that rewrites packet headers in flight. Before editing, the kernel is supposed to make the target page private — the standard copy-on-write pattern via skb_ensure_writable() — so the write can't touch memory shared with anyone else.
The bug is in tcf_pedit_act(): it computes the size of the region to privatize exactly once, up front, from a pre-calculated maximum hint — before the per-key loop resolves the actual runtime header offsets that typed pedit keys introduce. Those runtime offsets shift the real write past the end of the region that was actually copied. The write then lands on page-cache pages that were never privatized, and the kernel scribbles attacker-controlled bytes into the in-memory image of whatever file those pages belong to. The upstream fix moves the skb_ensure_writable() call inside the key loop so the COW range tracks the real offsets.
Because the corruption hits the page cache and never the disk, on-disk integrity checks see nothing: the file on storage is pristine while every process executing the cached copy — including setuid binaries like /bin/su — runs the attacker's bytes. That is what turns a networking bug into a root shell.
The hard facts: CVE-2026-46331, CVSS 7.8 (High), present from v5.18 through v7.1-rc6 (introduced by commit 899ee91156e5), fixed in v7.1-rc7. The prerequisites are an act_pedit module the kernel can load and unprivileged user namespaces enabled — the default on both RHEL-family and Debian-family installs — or CAP_NET_ADMIN outright.
net/sched is already on your nodes
The instinctive response from a platform team is "we don't run tc rules, so we're not exposed." That defense fails twice: once on the code being present, and once on who is allowed to reach it.
First, the code is present on effectively every Kubernetes node whether any human ever typed a tc command or not. The stock bandwidth CNI plugin programs tc qdisc ... tbf on the host end of every shaped pod's veth pair and injects an ifb device into the host network namespace for ingress shaping. Cilium and Calico in eBPF mode attach their datapath programs at the clsact qdisc — the traffic-control layer. Traffic control on a Kubernetes node is not an optional QoS hobby; it is load-bearing plumbing the CNI installed for you.
Second, the capability needed to reach it is handed out by default. Inside an unprivileged user namespace, an unprivileged UID holds CAP_NET_ADMIN over its own network namespace — enough to configure tc actions including pedit, which is precisely the path the public exploit takes. The attacker doesn't need your CNI's configuration or your host's tc rules to exist. They bring their own namespace, their own interfaces, and their own pedit rule, and the vulnerable code is the kernel's, shared across every namespace on the machine.
So the exposure question was never "do we use traffic shaping." It is "do our nodes run a vulnerable kernel with user namespaces enabled" — and for most fleets in June 2026, the answer was yes on both counts.
Five subsystems, one failure mode
Step back and look at the table as a whole, because the pattern across the five rows matters more than any single row:
- CopyFail (crypto): a logic flaw in the
authencesntemplate, reachable viaAF_ALGsockets plussplice(), writing four bytes into any readable file's page cache. In-tree since 4.14 (2017). Deterministic, first-try, CISA KEV-listed. - ITScape (KVM/arm64): a race in GICv3 interrupt-translation emulation, the first publicly demonstrated guest-to-host escape on ARM64, dropping a root-owned file on the host filesystem as proof.
- pedit COW (
net/sched): the stale-COW-hint write described above, in packet-editing code. - GhostLock (futex): a use-after-free in
rtmutexpriority-inheritance cleanup, clearing the wrong thread's bookkeeping. In-tree for roughly fifteen years, needs only the default-onCONFIG_FUTEX_PI, and ships a 97%-reliable exploit. - Januscape (KVM/x86): a shadow-MMU use-after-free, in-tree for roughly sixteen years, escaping guests to hosts on both Intel and AMD — with a companion fix (CVE-2026-46113) that has to land alongside it or the host stays exposed.
Five subsystems — crypto, two corners of KVM, futex locking, traffic control — that share almost no code and no maintainers. Two of the five aim at the same target, the shared page cache, which is what makes a local bug a container escape rather than mere local root: the page cache doesn't belong to your container, your pod, or your tenant. It belongs to the node.
That convergence kills the obvious containment strategy. After CopyFail, a team could blacklist algif_aead. After pedit COW, a team can blacklist act_pedit. But nobody maintains a blacklist entry for a subsystem they never suspected, and this window proves the suspect list is "the whole kernel": QoS packet editing and authenticated-encryption templates are not where any fleet's threat model had its attention in April. Per-subsystem mitigations are whack-a-mole with a molehill the size of net/, kernel/, crypto/, and virt/ combined.
The honest reframing: these are not five networking bugs or five crypto bugs. They are five instances of one failure mode — an unprivileged execution context reaching a host-wide kernel resource it should never be able to write — surfacing wherever the next unaudited code path happens to be. The window will keep producing entries until patching, not predicting, becomes the control.
What a fleet operator does this week
Concretely, for a Cluster-API-managed fleet on owned machines, the response to pedit COW specifically — and to the window generally — looks like this:
- Patch to a fixed kernel and reboot. pedit COW is fixed in v7.1-rc7 and backported stable trees; every sibling in the table has a fixed version too. There is no configuration that makes a vulnerable kernel safe, only mitigations that narrow the path. This is the step that actually closes the hole.
- Blacklist
act_peditwhere nothing needs it. If no workload or CNI path on the node programs pedit rules,install act_pedit /bin/trueinmodprobe.dremoves the trigger entirely. Verify first — an audit that breaks the CNI's datapath is worse than the risk it removes. - Make an explicit user-namespace policy. Disabling unprivileged user namespaces (
user.max_user_namespaces=0on RHEL-family,kernel.unprivileged_userns_clone=0on Debian-family) removes the capability source for pedit COW and several siblings at once — but it also breaks rootless containers and sandboxed browsers. That tradeoff deserves a written decision per node pool, not a default nobody chose. Note that Ubuntu 24.04 and later add partial AppArmor namespace restrictions, which narrow but don't remove the exposure. - Audit
tcrules fleet-wide. Enumerate programmed qdiscs, filters, and actions on every node so you know which machines actually load pedit-class code versus merely carrying it. On a declarative fleet this belongs in the node image definition, not in SSH history. - Drop caches after mitigating. Poisoned pages survive the fix that stops new poisoning;
echo 3 > /proc/sys/vm/drop_cachesevicts them. Fold this into the remediation runbook, not just the advisory.
And structurally: make the patch step boring. A fleet that reconciles every node to a declared machine image on a fixed cadence absorbs a ten-week, five-CVE window as routine rollouts. A fleet that patches by hand absorbs it as five emergencies. The CVEs are the input you can't control; the cadence is the control you can.
The window is the message
Any one of these five bugs is a patch-and-reboot footnote. Together, inside ten weeks, they are a statement about where kernel risk lives now: not in the exotic corners, but in everyday infrastructure code — packet editors, crypto templates, lock cleanup paths — that every node loads and almost nobody audits. The next entry in the tracker will come from a sixth subsystem nobody has named yet, and the teams that handle it calmly will be the ones whose fleets already patch like clockwork.
That is an argument for owning the machine lifecycle declaratively. When desired state is a manifest and reconciliation is continuous, "every node on a fixed kernel by Friday" is a one-line change rolled out by controllers — not a ticket queue, not a maintenance window negotiated team by team.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with declarative machine lifecycle that makes fleet-wide patching routine instead of heroic. Star the repo on GitHub or deploy your first app today.



