
Hoplon InfoSec
27 Jun, 2026
Content Summary
CVE-2026-46331, nicknamed "pedit COW," is a Linux kernel local privilege escalation vulnerability in the net/sched traffic-control subsystem. The flaw sits inside tcf_pedit_act(), where a partial copy-on-write failure lets an unprivileged local user corrupt shared page-cache memory and inject shellcode into a setuid binary's in-memory image, delivering a root shell without touching a single byte on disk.
A public PoC named packet_edit_meme appeared on GitHub within 24 hours of CVE assignment on June 16, 2026. Red Hat rates the bug as "important." The bug was introduced in Linux v5.18 and is present through v7.1-rc6. The upstream fix landed in v7.1-rc7. Patching and rebooting are the only complete remediation.
| Field | Detail |
|---|---|
| CVE ID | CVE-2026-46331 |
| Nickname | pedit COW |
| Severity | Important (Red Hat RHSB-2026-008) |
| Bug Class | CWE-787: Out-of-Bounds Write / Page Cache Corruption |
| Subsystem | Linux kernel net/sched, act_pedit (tcf_pedit_act()) |
| Affected Kernel Versions | v5.18 through v7.1-rc6 (introduced by commit 899ee91156e5) |
| Fixed In | v7.1-rc7; Debian package 6.12.94-1 |
| PoC Name | packet_edit_meme (GitHub) |
| PoC Released | June 17, 2026 (24 hours after CVE assignment) |
| CVE Assigned | June 16, 2026 |
| Patch Origin | netdev mailing list, late May 2026 |
| Exploit Type | Local Privilege Escalation (LPE), unprivileged to root |
| Vendor Errata | RHSA-2026:27288 (RHEL 10), RHSA-2026:27789 (RHEL 9), RHSA-2026:27353 (RHEL 8), DSA-6355-1 (Debian 13) |
A local user with no special permissions opens a terminal, runs a few commands, and thirty seconds later has a root shell. No password prompt. No file permission bypass. Nothing changed on disk. The file-integrity monitor displays a consistent green status. This is what CVE-2026-46331 looks like in practice, and it is precisely why this vulnerability belongs at the top of every Linux team's patching queue right now.
CVE-2026-46331 is an out-of-bounds write vulnerability inside the Linux kernel's traffic-control subsystem, specifically inside the packet-editing action called act_pedit. The flaw earned the nickname "pedit COW" because it breaks the kernel's copy-on-write safety mechanism in a way that lets writes escape from private memory into shared page-cache memory, which backs real files.
The result is a textbook Linux local privilege escalation. An unprivileged user on a standard Linux workstation, server, CI/CD runner, or Kubernetes node can exploit the bug to corrupt the in-memory image of a setuid binary and execute that corrupted image as root. The file on disk is never touched.
The bug was introduced by commit 899ee91156e5, present from Linux v5.18 through v7.1-rc6. That is a range spanning roughly four years of kernel development and covers virtually every actively maintained Linux distribution shipping today.
A public proof-of-concept exploit was released within a day of the CVE being assigned on June 16, significantly increasing the risk for unpatched systems. The PoC, named packet_edit_meme, is publicly available on GitHub and has been confirmed to work against production systems. Red Hat classified the flaw as important and published an official security bulletin under RHSB-2026-008.
This classification matters beyond just another kernel CVE. The reason security teams need to understand the mechanics here is that standard defensive tooling, including file-integrity monitors, antivirus, and disk-based scanners, will not catch an active exploit. By the time your AIDE scan comes back clean, an attacker may already own the machine.
To understand why this vulnerability is so effective, you need to understand what the affected code is actually supposed to do.
Linux's tc (traffic control) framework is a powerful tool for managing network traffic. Among many things, it supports an action called "pedit," short for "packet edit," which rewrites packet headers as they travel through the kernel's networking stack. A system administrator might use a TCPedit rule to rewrite source IP addresses, modify DSCP markings, or alter Ethernet header fields on packets in flight.
The kernel function that implements this, tcf_pedit_act(), is supposed to follow a standard copy-on-write pattern before making any modifications. The idea is simple: before you write to a page of memory, make a private copy of it. That way, your changes affect only your copy and never touch shared memory that other processes might be reading.
The bug arises because the code computes the copy-on-write range for skb_ensure_writable() once before iterating over edit keys, using tcfp_off_max_hint. That hint does not include the runtime header offset introduced by typed keys, so the actual write location for a given key can extend beyond the region that was made writable.
In plain terms: the kernel checks the writable range once, at the start, using an approximation of how far the writes will reach. But some petite edit keys only resolve their final memory offset at execution time. When those keys run, the write lands past the boundary of the privately copied region, straight into a shared page-cache page.
The fix moves skb_ensure_writable() into the per-key loop so the writable range is calculated using the actual write offset for each key, adds overflow checks to offset arithmetic, uses skb_cow() for negative offsets such as Ethernet header edits at ingress to ensure headroom is properly COW'd, and hardens offset_valid() against INT_MIN negation edge cases.
The page cache is the kernel's in-memory representation of files. When any process reads a file from disk, the kernel loads it into page-cache pages and keeps it there. If two processes read the same file, they share the same physical page-cache pages. This is efficient but also means that a write into one of those pages becomes visible to anyone reading that file, including the kernel itself when it executes a binary.
The exploit never touches the disk. It spawns a user namespace child to obtain CAP_NET_ADMIN, then uses the COW corruption primitive to overwrite the page-cached ELF entry point of the setuid-root binary /bin/su in the kernel page cache. It overwrites the binary's entry point with shellcode setgid(0), followed by setuid(0), followed by execve("/bin/sh"), and then triggers the poisoned image to drop a root shell.
The file on disk is untouched. An integrity check against the on-disk binary will report no changes. A root shell is already open.
The exploit needs exactly two conditions to be true simultaneously. The attack vector is local, complexity is low once the prerequisites are present, there is no user interaction required, and exploitation results in deterministic page-cache corruption to root with working public exploit code.
Condition one: The act_pedit kernel module must be loadable. On most Linux distributions it is either already loaded or can be loaded without any elevated privileges.
Condition two: Unprivileged user namespaces must be enabled. On RHEL and Debian, user.max_user_namespaces is greater than zero by default. On Ubuntu 24.04, unprivileged user namespaces are accessible through AppArmor profiles that still permit namespace creation.
User namespaces are the key to making this exploit reachable. When an unprivileged process creates a user namespace, it receives full administrative capabilities scoped to that namespace, including CAP_NET_ADMIN. That namespace-local capability is all the exploit needs to configure tc pedit rules and trigger tcf_pedit_act().
Here is the full exploit chain step by step:
The attacker spawns a child process inside a new user namespace.
The child process acquires namespace-local CAP_NET_ADMIN automatically on namespace creation.
Using that capability, the attacker configures a TCP edit rule targeting the loopback interface and calibrates the file-offset delta using a temporary calibration file.
Traffic sent via sendfile triggers tcf_pedit_act(), which computes the COW range using the stale tcfp_off_max_hint approximation.
A runtime-resolved edit key writes beyond the COW'd region, hitting a shared page-cache page that backs /bin/su.
The ELF entry point of the in-memory /bin/su image is overwritten with shellcode executing setgid(0), setuid(0), and execve("/bin/sh").
The attacker calls /bin/su. The kernel executes the poisoned in-memory image.
A root shell drops. The file on disk is unchanged. File-integrity scanners report nothing.
Whether hardware mitigations like SMAP and SMEP offer any resistance here is worth noting. They do not. Those mitigations prevent the kernel from accidentally executing or dereferencing user-space memory, but the attack here stays entirely within kernel page-cache memory. The exploit never plants code in user space and expects the kernel to jump there. The corruption happens inside the kernel's own page cache, which SMAP and SMEP are not designed to protect.
SELinux in enforcing mode does not block the exploit either on the tested configurations because the namespace and networking operations used fall within normal policy. AppArmor provides partial exposure reduction, as discussed in the distribution section below.
CVE-2026-46331 did not arrive in a vacuum. It belongs to a growing family of Linux kernel page-cache corruption vulnerabilities that share a single architectural pattern, and understanding that pattern explains why these bugs keep appearing.
Dirty Pipe (CVE-2022-0847) was the bug that put this class on the map. It exploited a flaw in the pipe splice path where the kernel would write into page-cache pages without verifying exclusive ownership, allowing an unprivileged user to overwrite arbitrary read-only files. The CVSS score was 7.8. It was straightforward to exploit and affected a massive number of systems.
After Dirty Pipe, researchers found Copy Fail, DirtyClone (CVE-2026-43503, CVSS 8.8), and Dirty Frag. Each one found a different kernel fast path that made the same wrong assumption: that a page was safe to write because it had been marked writable, without verifying that the write region was actually exclusively owned.
These bugs are dangerous precisely because they convert local memory corruption into something practical. An attacker does not have to defeat file permissions or modify anything on disk. They only need to corrupt the cached copy long enough for privileged code to read or execute it.
What makes CVE-2026-46331 different from its predecessors is the entry point. Dirty Pipe used the pipe splice subsystem, which required specific file operations. pedit COW uses the traffic-control subsystem, which is reachable from inside a user namespace. That is a broader attack surface. Virtually any local user on a modern Linux system, including users inside containers or CI jobs, can create a user namespace and reach this code path.
The deeper fix is not "stop optimizing." It is stronger page-ownership guarantees throughout the kernel's memory-handling paths, slowing work because it touches the most performance-sensitive parts of the kernel. Until that systemic work is done, expect more entries in this family.
| Distribution | Status | Notes |
|---|---|---|
| Debian 13 (Trixie) | Patched | DSA-6355-1; upgrade to package version 6.12.94-1 or later |
| Debian 12 (Bookworm) | Vulnerable | No fix listed as of June 25, 2026 |
| Debian 11 (Bullseye) | Vulnerable | No fix listed as of June 25, 2026 |
| Ubuntu 26.04 | Reduced exposure | AppArmor restricts unprivileged user namespaces by default; underlying kernel still vulnerable |
| Ubuntu 24.04 | Exploitable via workaround | Attacker routes through AppArmor profiles that still permit namespace creation |
| Ubuntu 18.04 to 22.04 | Vulnerable | All supported releases as of June 25, 2026 |
| RHEL 10 | Patched | RHSA-2026:27288 |
| RHEL 9 | Patched | RHSA-2026:27789 |
| RHEL 8 | Patched | RHSA-2026:27353; EUS/TUS variant RHSA-2026:27355 |
| RHEL 7 | Not listed | Not included in Red Hat bulletin |
| AlmaLinux 8 | Patched | ALSA-2026:27353 |
A note on Ubuntu 26.04: the AppArmor policy that ships by default blocks unprivileged user namespace creation, which removes condition two of the exploit chain. The kernel itself is still vulnerable; if an attacker finds another way to obtain CAP_NET_ADMIN, the page-cache corruption is still reachable. It is exposure reduction, not a fix.
Fedora and Arch Linux ship rolling kernels and will have received the fix in any build containing v7.1-rc7 or the stable backport commits 899ee91156e5, 2bec122b9fb9, 3dee9d0c198f, and b198ed4e5258. Check your installed kernel version against those references.
This is where the vulnerability gets genuinely uncomfortable for most security teams.
File-integrity monitoring tools like AIDE, Tripwire, and auditd file watches all operate on the same premise: they compare the cryptographic hash of a file on disk to a known-good baseline. They do not inspect the kernel's page cache. /bin/su on disk is clean. In memory, it is a shellcode launcher. Every FIM tool you run will report no changes.
echo 3 > /proc/sys/vm/drop_caches will flush the poisoned in-memory copy and replace it with the clean version from disk on the next access. But that command does nothing about a root shell already running in another terminal. If you are running that command in response to a suspected exploit, you are not cleaning up. You are closing the barn door after the horse has left, saddled and galloping. Treat the host as fully compromised.
What actually has a chance of catching this exploit in flight or shortly after:
Behavioral detection via auditd: The exploit's root shell spawns with /bin/su as the parent process, which is abnormal. ausearch -k execve filtered for su spawning a shell child will surface this. Set up an auditctl rule watching execve calls where the parent is a setuid binary.
EDR process lineage rules: Any extended detection and response platform that builds process trees should flag a shell process whose parent is /bin/su with no corresponding authentication event. That lineage is not possible under normal operation.
eBPF-based runtime security: Tools like Falco and Tetragon can observe kernel events at the syscall level. A Falco rule watching for execve where the spawning process is a setuid binary and the resulting process is a shell, combined with no PAM authentication event, is a viable detection signal. It will not catch the page cache write itself, but it catches the exploitation outcome.
Namespace creation monitoring: Monitor for unexpected user namespace creation events using auditd with -a always,exit -F arch=b64 -S unshare -k namespace_create. Legitimate user namespace creation on production servers is rare. On CI runners it is normal but should correlate with known job identities.
/proc/<pid>/maps inspection: If you suspect a process is executing a corrupted binary, inspect its memory map with cat /proc/<pid>/maps. Compare the mapped region addresses against a known-clean run of the same binary. Discrepancies in the mapped ELF segments can indicate in-memory modification.
The honest assessment is that most standard enterprise security stacks will not catch this without specific tuning. The vulnerability management answer here is patch first, then build detection as a secondary layer.
Remediation: Patch, Mitigate, and Respond
There is no way around this. Install the vendor-provided patched kernel and reboot the host. The kernel cannot be hotpatched for a bug of this class on most distributions. The reboot also flushes any page-cache pages that may have been corrupted during the exposure window, replacing them with clean copies from disk on next access.
Priority patching order: multi-tenant Linux hosts, CI/CD runners, Kubernetes nodes, build workers, shared research or lab machines, and any system where "local user" does not mean a fully trusted individual. Single-user developer workstations should still be patched but are a lower immediate risk.
If your systems run no TCPEDIT rules for QoS or traffic shaping, blocking the module eliminates condition one of the exploit chain.
bash
# Check if the module is currently loaded
lsmod | grep act_pedit
# Block it from loading permanently
echo 'install act_pedit /bin/true' | sudo tee /etc/modprobe.d/disable-act_pedit.conf
Caveat: If you run legitimate TC PEDIT rules for traffic manipulation, this will break them. Audit before applying. This is worth checking via your attack surface management process.
This eliminates condition two of the exploit chain by removing the attacker's path to namespace-local CAP_NET_ADMIN.
On RHEL:
bash
sysctl -w user.max_user_namespaces=0
echo 'user.max_user_namespaces=0' | sudo tee /etc/sysctl.d/99-disable-userns.conf
On Debian and Ubuntu:
bash
sysctl -w kernel.unprivileged_userns_clone=0
echo 'kernel.unprivileged_userns_clone=0' | sudo tee /etc/sysctl.d/99-disable-userns.conf
Caveat: This breaks rootless containers (Podman, rootless Docker), some CI sandbox environments, and sandboxed Chromium and Firefox builds. Test this change in a staging environment before rolling out to production. On Kubernetes nodes, check whether your CNI plugin or runtime relies on unprivileged namespace creation.
bash
echo 3 > /proc/sys/vm/drop_caches
This clears the poisoned in-memory copy if exploitation is suspected but not yet confirmed. Again: this does nothing about a root shell already running. If you have any reason to believe the exploit ran on a host during the exposure window, the correct response is to treat that host as compromised, engage your incident response and recovery process, and begin forensic investigation rather than attempting to clean the running system.
Patch urgency matrix:
| System Type | Urgency | Reasoning |
|---|---|---|
| Multi-tenant Linux server | Critical, patch tonight | Any local user is a potential attacker |
| CI/CD runner / build worker | Critical | Jobs from multiple teams or external PRs run as local users |
| Kubernetes node | Critical | Container escape via LPE is a realistic threat path |
| Internet-facing application server | High | If web shell or RCE exists, LPE turns it into full root |
| Single-user developer workstation | Medium | Only the owner is local, but patch in next maintenance window |
| Air-gapped isolated server | Medium | Lower immediate risk but still affected; patch at next window |
For teams that need to assess exposure across their fleet before patching, running uname -r across all hosts and comparing against the affected range (v5.18 through v7.1-rc6) gives a quick triage view. Your cyber resilience assessment process should already have a kernel version inventory; use it.
The story of how CVE-2026-46331 came to light is almost as important as the vulnerability itself because it exposes a structural problem in how kernel security disclosures work.
The fix was developed in the open on the netdev mailing list as a routine data-corruption patch with the subject line "net/sched: fix pedit partial COW leading to page cache corruption," with no CVE and no security framing. The kernel.org CNA assigned CVE-2026-46331 at merge time on June 16, 2026, weeks after the exploitable technical detail was already public, and a weaponized PoC dropped June 17.
That timeline means anyone monitoring the netdev mailing list closely saw the exact nature of the bug, including the fact that it involved page-cache corruption via act_pedit, weeks before any CVE existed. A sophisticated attacker reading the patch subject line and the diff could have built a working exploit during that window. Defenders, meanwhile, had no CVE, no vendor advisory, no scanner rule, and no patch process attached to it because from the outside it looked like a boring data-corruption fix.
This is not unique to this vulnerability. It is a recurring structural issue in open-source kernel development. Fixes for security-sensitive bugs regularly travel as correctness or stability fixes without explicit security labeling. By the time a CVE is assigned and vendors ship errata, the technical disclosure has already been public for weeks or months.
What this means practically: if your security posture depends entirely on CVE scanners, you have a gap. Monitoring the netdev mailing list is not realistic for most teams, but using a cyber threat intelligence service that tracks kernel patch traffic for security-relevant patterns is a way to close that gap. The alternative is accepting that you will always be reacting to a CVE that was exploitable long before you knew it existed.
For teams conducting penetration testing exercises or AI-driven automated red teaming engagements, CVE-2026-46331 is a strong reminder to include local privilege escalation paths in scope. LPE vulnerabilities regularly provide the pivoting step that turns a low-privilege foothold into full infrastructure access.
Do I need physical access to exploit CVE-2026-46331?
No. Physical access is not required. The exploit runs entirely from an existing local shell session, which includes SSH sessions, terminal access on shared hosts, container escapes that provide a local shell, or CI job runners where the attacker can execute arbitrary commands.
Does this affect cloud VMs or only bare metal?
Cloud VMs are affected if they run a vulnerable kernel version and have unprivileged user namespaces enabled. Most major cloud providers run guest kernels that are customer-controlled, so the patching responsibility falls on the VM owner. The hypervisor layer provides no protection against an in-guest LPE.
Will my antivirus or EDR detect this exploit?
Standard antivirus will not. EDR platforms may detect the exploitation outcome (a shell spawned as a child of /bin/su with no authentication event) if they have behavioral rules for anomalous process lineage. Check with your EDR vendor on whether they have released a specific detection rule for packet_edit_meme signatures.
Is rootless Docker or Podman affected?
Both rootless Docker and rootless Podman rely on unprivileged user namespaces. If you disable user namespaces as a mitigation, rootless container workflows will break. If you keep user namespaces enabled, any user with access to run rootless containers has the prerequisite for this exploit.
Does Ubuntu 26.04's AppArmor fully block this?
No. Ubuntu 26.04's AppArmor default policy restricts unprivileged user namespace creation, which removes the attacker's path to namespace-local CAP_NET_ADMIN. This reduces exposure significantly but is not a complete fix. The underlying kernel code is still vulnerable. If an attacker already has CAP_NET_ADMIN through another path, the exploit still works.
How is this different from Dirty Pipe (CVE-2022-0847)?
Both corrupt the Linux page cache to inject shellcode into a setuid binary's in-memory image. The difference is the entry point. Dirty Pipe used the pipe splice subsystem, which required specific file operations. pedit COW uses the tc traffic-control subsystem, reachable from inside a user namespace. The pedit COW's entry point is broader and more consistently accessible across distribution default configurations.
Can dropping the page cache undo an active compromise?
No. Dropping the page cache with echo 3 > /proc/sys/vm/drop_caches flushes the corrupted in-memory binary and replaces it with the clean disk copy on next access. It does not terminate processes already running, including a root shell spawned before the flush. If exploitation is suspected, treat the host as compromised and follow your incident response plan.
Will my file-integrity monitor (AIDE/Tripwire) catch this?
No. AIDE, Tripwire, and similar tools compare cryptographic hashes of files on disk to a baseline. They do not inspect the kernel's page cache. The on-disk binary is unchanged. These tools will report clean while the in-memory image is corrupted.
Does disabling user namespaces break Kubernetes?
It depends on your Kubernetes configuration. Some CNI plugins and container runtimes use user namespaces. Check your specific CNI, CRI, and runtime versions before disabling. A test in a staging Kubernetes cluster is strongly recommended before applying to production nodes.
When will all major distros have patches available?
Red Hat (RHEL 8, 9, 10) and Debian 13 (Trixie) have shipped patches. Debian 11 and 12 patches were not yet listed as of June 25, 2026. Ubuntu patches across versions 18.04 through 26.04 were not yet listed as of June 25, 2026. Check your vendor's security tracker directly for the most current status.
Author: Hoplon InfoSec Research Team
Cybersecurity Analysts | Hoplon InfoSec
The Hoplon InfoSec Research Team is a group of certified cybersecurity professionals specializing in vulnerability research, threat intelligence, penetration testing, and enterprise security operations. All published content is grounded in hands-on technical research and verified against official vendor advisories to deliver immediately actionable guidance for security practitioners.
Learn more at hoploninfosec.com
Was this article helpful?
React to this post and see the live totals.
Share this :