DirtyClone — Linux Kernel LPE via Cloned Packet Page-Cache Overwrite (CVE-2026-43503)
by Hyunwoo Kim (patch author); Eddy Tsalolikhin, Or Peles (JFrog Security Research, exploit writeup); rafaeldtinoco (PoC) · 2026-06-28
- Severity
- High
- CVE
- CVE-2026-43503
- Category
- binary
- Affected product
- Linux kernel (netfilter TEE / __pskb_copy_fclone())
- Affected versions
- All kernels before commit 48f6a5356a33 (v7.1-rc5, May 21 2026); Linux 6.1–6.12 confirmed; 5.15 and 5.10 LTS under investigation
- Disclosed
- 2026-06-28
- Patch status
- patched
Tags
References
- https://research.jfrog.com/post/dissecting-and-exploiting-linux-lpe-variant-dirtyclone-cve-2026-43503/
- https://github.com/rafaeldtinoco/security/tree/main/exploits/dirtyclone
- https://thehackernews.com/2026/06/new-dirtyclone-linux-kernel-flaw-lets.html
- https://www.scworld.com/news/2-linux-kernel-flaw-pocs-published-enabling-local-privilege-escalation
- https://nvd.nist.gov/vuln/detail/CVE-2026-43503
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-06-28 |
| Last Updated | 2026-06-28 |
| Author / Researcher | Hyunwoo Kim (patch author); Eddy Tsalolikhin, Or Peles (JFrog Security Research, exploit writeup); rafaeldtinoco (PoC) |
| CVE / Advisory | CVE-2026-43503 |
| Category | binary |
| Severity | High |
| CVSS Score | 8.8 (CVSSv3) |
| Status | Weaponized |
| Tags | LPE, Linux kernel, netfilter, TEE, IPsec, XFRM, page-cache, file-backed memory, DirtyFrag, skb, privilege escalation, C, in-the-wild |
| Related | CVE-2026-31431, CVE-2026-43284, CVE-2026-43500, CVE-2026-46300 |
Affected Target
| Field | Value |
|---|---|
| Software / System | Linux kernel (netfilter TEE / __pskb_copy_fclone()) |
| Versions Affected | All kernels before commit 48f6a5356a33 (v7.1-rc5, May 21 2026); Linux 6.1–6.12 confirmed; 5.15 and 5.10 LTS under investigation |
| Language / Platform | C, Linux |
| Authentication Required | Yes (local unprivileged shell) |
| Network Access Required | Local only (loopback IPsec tunnel) |
Summary
DirtyClone (CVE-2026-43503, CVSS 8.8) is the fourth member of the DirtyFrag family of Linux kernel local privilege escalation vulnerabilities. Each member shares the same root failure: file-backed page-cache memory is exposed to network packet operations, and a missing flag along the code path turns a zero-copy performance optimisation into an arbitrary write primitive.
DirtyClone’s specific path runs through the netfilter TEE target, which clones outbound packets via __pskb_copy_fclone(). That function drops the SKBFL_SHARED_FRAG flag, the same safety bit that the original DirtyFrag mitigation introduced. With the flag gone, the kernel’s in-place IPsec ESP decryption (esp_input() / AES-CBC) overwrites page-cache pages the attacker mapped from a privileged binary such as /usr/bin/su. The binary on disk is never touched; the modification lives only in memory, making the attack invisible to file-integrity tools and self-cleaning on reboot.
JFrog Security Research (Eddy Tsalolikhin, Or Peles) published the first public exploit walkthrough on June 25, 2026. A working C PoC was released by rafaeldtinoco. The patch (commit 48f6a5356a33) was merged May 21 into Linux v7.1-rc5 and covers __pskb_copy_fclone(), skb_shift(), and additional frag-transfer helpers.
Vulnerability Details
Root Cause
The Linux kernel’s zero-copy networking allows file-backed page-cache pages to serve as packet fragment data. Whenever the kernel moves such fragments between socket buffers, it must propagate the SKBFL_SHARED_FRAG flag to signal that those pages are shared with the page cache and must not be modified in place.
__pskb_copy_fclone(), called by the netfilter TEE target to duplicate outbound packets, fails to copy this flag to the cloned skb. A second affected helper, skb_shift(), has the same omission. Once the flag is absent, IPsec ESP processing treats the fragment as ordinary packet data and decrypts it in place — overwriting the page-cache copy of whatever file the attacker pinned there.
The broader CVE covers all frag-transfer helpers where the contract was not honoured; the demonstrated exploit path centres on TEE + __pskb_copy_fclone().
Family Timeline
| Date | CVE | Name | Path |
|---|---|---|---|
| Late Apr 2026 | CVE-2026-31431 | Copy Fail | algif_aead / AF_ALG AEAD splice — 4-byte write |
| May 7 2026 | CVE-2026-43284, CVE-2026-43500 | DirtyFrag | IPsec ESP + RxRPC — full write primitive |
| May 13 2026 | CVE-2026-46300 | Fragnesia | skb_try_coalesce() flag-drop bypass of DirtyFrag patch |
| May 21 2026 | CVE-2026-43503 | DirtyClone | __pskb_copy_fclone() + skb_shift() via netfilter TEE |
Attack Vector
Obtain CAP_NET_ADMIN — On Debian and Fedora (unprivileged user namespaces enabled by default), a local user creates a new user namespace to gain the capability. Ubuntu 24.04+ with AppArmor namespace restrictions blocks this step, requiring an alternative capability source.
Pin privileged binary into page cache — Open
/usr/bin/suand usevmsplice/spliceto map its pages into a pipe, keeping them resident in the page cache.Wire pages into a network packet — Splice the pipe data into a raw socket so the kernel creates a socket buffer (
skb) whose fragment directly references the page-cache pages.Configure loopback IPsec tunnel — Set up an XFRM/IPsec ESP tunnel in the namespace with an AES-CBC key and IV chosen to produce a known, attacker-controlled plaintext after decryption.
Add netfilter TEE rule — Install an iptables TEE rule that duplicates packets leaving the loopback interface, invoking
__pskb_copy_fclone()on each one. The cloned skb losesSKBFL_SHARED_FRAG.Trigger in-place decrypt — Transmit the crafted packet. IPsec processes the clone,
esp_input()decrypts the fragment in place, and the decrypted (attacker-chosen) bytes are written into the page-cache copy of/usr/bin/su.Gain root — Execute
su. The patched in-memory binary skips authentication and spawns a root shell.
The disk binary is unchanged; the write affects only the kernel’s cached copy. File-integrity monitoring, dm-verity, and audit logs see nothing. A system reboot restores the original binary.
Impact
- Full local privilege escalation to root (uid=0) from any unprivileged shell.
- Modification is in-memory only — invisible to file-integrity tools and self-cleaning on reboot.
- In container/namespace environments, page cache is shared at host level: a write from inside a namespace affects every process on the host.
- Highest-risk environments: multi-tenant servers, CI runners, container hosts (Docker, Podman), Kubernetes nodes where untrusted users can run workloads.
Environment / Lab Setup
OS: Debian 12 / Ubuntu 22.04 / Fedora 41 (default namespace config)
Kernel: < v7.1-rc5 (before commit 48f6a5356a33)
Attacker: Local unprivileged user
Tools: gcc, make, iptables/nft, iproute2 (ip xfrm)
Setup Steps
| |
Proof of Concept
Step-by-Step Reproduction
Verify namespace access — Confirm unprivileged user namespaces are enabled.
1 2cat /proc/sys/kernel/unprivileged_userns_clone # Debian: 1 cat /proc/sys/user/max_user_namespaces # > 0Build exploit
1cd security/exploits/dirtyclone && makeRun as unprivileged user
1./dirtycloneConfirm escalation
1 2id # uid=0(root) gid=0(root) groups=0(root)
Exploit Code
See
dirtyclone.cin the upstream repo atrafaeldtinoco/security/exploits/dirtyclone/.
The exploit:
- Creates a user namespace to acquire CAP_NET_ADMIN.
- Opens
/usr/bin/su, splices pages into page cache via vmsplice. - Configures a loopback XFRM/IPsec ESP tunnel with attacker-chosen AES-CBC key/IV.
- Installs a netfilter TEE rule to trigger
__pskb_copy_fclone(). - Transmits the crafted skb;
esp_input()overwrites page-cache bytes in place. - Executes the patched
subinary to obtain a root shell.
Expected Output
[*] Creating user namespace...
[*] Configuring loopback XFRM tunnel...
[*] Installing netfilter TEE rule...
[*] Splicing /usr/bin/su into page cache...
[*] Triggering __pskb_copy_fclone() path...
[*] Page-cache overwrite complete.
[*] Executing patched su...
uid=0(root) gid=0(root) groups=0(root)
Detection & Indicators of Compromise
auditd rules:
-a always,exit -F arch=b64 -S vmsplice -k dirtyfrag_family
-a always,exit -F arch=b64 -S unshare -F a0=0x10000000 -k userns_create
Mitigation (without patching):
| |
Remediation
| Action | Detail |
|---|---|
| Patch | Update to Linux kernel ≥ v7.1-rc5 (commit 48f6a5356a33) or apply distro backport |
| Workaround | sysctl kernel.unprivileged_userns_clone=0 (Debian/Fedora); Ubuntu 24.04+ AppArmor profile already blocks default path |
| Verification | uname -r — confirm kernel includes commit 48f6a5356a33 via distro changelog or git log |
References
| |