CVE-2026-43503: Verified Repro With Script Download
CVE-2026-43503: DirtyClone Linux kernel page-cache corruption privilege escalation
CVE-2026-43503 is verified against Linux kernel · linux. Vulnerability class: Privilege Escalation. This high reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00212.
What Is CVE-2026-43503?
CVE-2026-43503, nicknamed DirtyClone, is a critical local privilege escalation vulnerability in the Linux kernel networking stack that allows an unprivileged local attacker to gain root code execution. Pruva reproduced it (reproduction REPRO-2026-00212).
CVE-2026-43503 Severity & CVSS Score
CVE-2026-43503 is rated high severity, with a CVSS base score of 8.8 out of 10.
High — serious impact or readily exploitable. Prioritize remediation.
How to Reproduce CVE-2026-43503
pruva-verify REPRO-2026-00212 curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00212/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-43503
- reached the target end-to-end
- full exploit chain demonstrated
- on the real production code path
- high confidence
- the upstream fix blocks the same trigger
unprivileged local attacker with XFRM/ESP + netfilter TEE + vmsplice/splice zero-copy data
- __pskb_copy_fclone() path via netfilter TEE; in-place ESP decryption over file-backed page cache
Fragnesia-style sibling variant of CVE-2026-43503 (DirtyClone) that uses ESP-in-TCP over veth and TCP receive coalescing (skb_try_coalesce) to reach the same in-place ESP-decryption sink over file-backed page-cache frags.
How the agent worked
Root Cause and Exploit Chain for CVE-2026-43503
CVE-2026-43503, nicknamed DirtyClone, is a local privilege escalation flaw in the Linux kernel networking stack. When a socket buffer (skb) carries file-backed page-cache fragments, the SKBFL_SHARED_FRAG flag in skb_shinfo()->flags tells the XFRM/IPsec receive path that it must copy the data before decrypting in-place. Several skb fragment-transfer helpers (__pskb_copy_fclone(), skb_shift(), skb_gro_receive(), skb_gro_receive_list(), tcp_clone_payload(), and skb_segment()) fail to copy that flag to the new skb. A netfilter TEE clone therefore keeps the original page-cache reference but no longer reports itself as shared/file-backed, so esp_input() decrypts directly into the page-cache page of a root-owned setuid binary. By choosing the AES-CBC key/IV so the decrypted bytes are attacker-controlled shellcode, the attacker rewrites e.g. /usr/bin/su in RAM and obtains a root shell when the binary is executed.
- Package/component affected: Linux kernel networking stack — specifically the skb fragment-copy helpers and the XFRM/IPsec
esp_input()path. - Affected versions: Mainline Linux before v7.1-rc5; stable branches before 5.10.257, 5.15.208, 6.1.174, 6.6.141, 6.12.91, 6.18.33, and 7.0.10.
- Risk level and consequences: Local privilege escalation. An unprivileged local user with the ability to create user and network namespaces can gain root code execution by corrupting the page cache of a setuid root binary. The bug is reachable from the normal networking paths used by XFRM/IPsec and netfilter, so no special hardware or third-party modules are required beyond the standard kernel configuration.
Impact Parity
- Disclosed/claimed maximum impact: Local privilege escalation (
privilege_escalation) — unprivileged attacker writes into a root-owned read-only binary's page cache and gains root. - Reproduced impact from this run: Full privilege escalation demonstrated. The reproducer runs as uid 1000, modifies
/usr/bin/suin the page cache, and the subsequentecho id | /usr/bin/suas the same uid 1000 user printsuid=0(root) gid=0(root) groups=0(root). - Parity:
full. - Not demonstrated: N/A — the claimed root shell was obtained.
Root Cause
The bug is in the skb fragment-copy routines. __pskb_copy_fclone() (and the other helpers listed above) copy the fragment array and page references from one skb to another, but they do not propagate the SKBFL_SHARED_FRAG flag from the source skb_shinfo()->flags. This flag is set by the DirtyFrag splice fix (f4c50a4034e6) whenever an skb carries file-backed page-cache fragments via vmsplice()/splice()` into a socket.
When the netfilter TEE target clones an outbound ESP-in-UDP packet, the clone goes through nf_dup_ipv4() → __pskb_copy_fclone(). The clone keeps a reference to the same physical page-cache page but is no longer marked SKBFL_SHARED_FRAG. On the receive side, esp_input() calls skb_cow_data() which checks skb_has_shared_frag(). Because the flag is missing, the cow path is skipped and the in-place AES-CBC decryption writes attacker-controlled bytes into the file-backed page-cache page.
The upstream fix is commit 48f6a5356a33dd78e7144ae1faef95ffc990aae0 (first tag v7.1-rc5), which propagates the SKBFL_SHARED_FRAG flag across the fragment-transfer helpers. Ubuntu mainline v7.0.10 contains the backport, so it serves as the negative control in this reproduction.
Reproduction Steps
The reproduction is fully automated by bundle/repro/reproduction_steps.sh. In short, it:
- Installs QEMU, busybox-static, cpio, gcc, coreutils, and jq if they are not present.
- Uses the prepared project cache to obtain the Ubuntu mainline v7.0.9 (vulnerable) and v7.0.10 (fixed) kernels plus matching rootfs images.
- Compiles the rafaeldtinoco
dirtyclone.cexploit and a smallrunashelper that drops to uid 1000. - Builds a custom initramfs that:
- mounts the rootfs read-only,
- switches root into the Ubuntu rootfs,
- loads
xt_TEE,nf_dup_ipv4,esp4, andxfrm_user, - runs the exploit as an unprivileged uid 1000 user,
- executes
echo id | /usr/bin/suas the same uid 1000 user.
- Boots each kernel/rootfs pair in QEMU with the initramfs and captures the console output.
- Checks that the vulnerable run prints
LPE_SUCCESSanduid=0(root), while the fixed run printsLPE_FAILandsu: Authentication failure. - Writes
bundle/repro/runtime_manifest.jsonandbundle/repro/validation_verdict.json.
Expected evidence
bundle/logs/qemu_vuln.logmust contain:Linux (none) 7.0.9-070009-generic ...,[dc] wrote 192 bytes to /usr/bin/su starting at 0x0,uid=0(root) gid=0(root) groups=0(root)from theidcommand,LPE_SUCCESS: unprivileged user got root.
bundle/logs/qemu_fixed.logmust contain:Linux (none) 7.0.10-070010-generic ...,[dc] post-write verify failed (target unchanged),Password: su: Authentication failure,LPE_FAIL.
Evidence
bundle/logs/reproduction_steps.log— high-level script progress.bundle/logs/qemu_vuln.log— full console capture of the vulnerable kernel run showing the root shell.bundle/logs/qemu_fixed.log— full console capture of the fixed kernel run showing the exploit is blocked.bundle/repro/runtime_manifest.json— runtime evidence manifest.bundle/repro/validation_verdict.json— structured verdict (claim_outcome: confirmed).
Key excerpts from the vulnerable run:
[dc] cmd: iptables -t mangle -A OUTPUT -p udp --dport 4500 -j TEE --gateway 10.99.0.2 -> 0
[dc] installed 48 xfrm SAs
[dc] wrote 192 bytes to /usr/bin/su starting at 0x0
[dc] /usr/bin/su page-cache patched (entry 0x78 = shellcode)
=== LPE check as uid 1000 ===
uid=0(root) gid=0(root) groups=0(root)
LPE_SUCCESS: unprivileged user got root
Key excerpts from the fixed run:
[dc] wrote 192 bytes to /usr/bin/su starting at 0x0
[dc] post-write verify failed (target unchanged)
=== LPE check as uid 1000 ===
Password: su: Authentication failure
LPE_FAIL
The kernel configuration required for the path is present in both Ubuntu mainline builds: CONFIG_XFRM, CONFIG_INET_ESP, CONFIG_NETFILTER_XT_TARGET_TEE, and user namespaces.
Recommendations / Next Steps
- Upgrade: Apply the upstream fix
48f6a5356a33(or the corresponding stable backport). Ubuntu mainline v7.0.10 and later, and mainline v7.1-rc5 and later, are patched. - Mitigation until patched: Disable unprivileged user namespaces (
kernel.unprivileged_userns_clone=0) or prevent loading ofxt_TEE/esp4/nf_dup_ipv4for untrusted users, since the exploit requiresCAP_NET_ADMINin a private network namespace. - Testing: Backport validation should verify that
SKBFL_SHARED_FRAGsurvives__pskb_copy_fclone(),skb_shift(),skb_gro_receive(),skb_gro_receive_list(),tcp_clone_payload(), andskb_segment()by running this reproducer against the candidate kernel.
Additional Notes
- Idempotency: The script was run twice consecutively from a clean state and produced the same confirmed verdict both times.
- Isolation: The rootfs disk is mounted read-only inside the VM and the QEMU drive is opened with
readonly=on, so the host-side image files are not modified by the exploit. - Limitations: The reproduction depends on the prebuilt Ubuntu mainline kernels and rootfs in the project cache. The exploit path uses
udp/4500ESP-in-UDP encapsulation and a netfiltermangle/OUTPUTTEE rule to force the__pskb_copy_fclone()clone; any kernel configuration that lacks one of these components will fail closed, which is expected behavior for an incomplete path.
Variant Analysis & Alternative Triggers for CVE-2026-43503
This variant stage investigated whether a different frag-transfer helper could bypass the CVE-2026-43503 fix. The candidate chosen was the Fragnesia path (CVE-2026-46300): instead of the original DirtyClone netfilter TEE → __pskb_copy_fclone() route, Fragnesia reaches the same XFRM/ESP in-place decryption sink through ESP-in-TCP (espintcp) over a veth pair, using TCP receive coalescing (skb_try_coalesce()) to move file-backed page-cache fragments into an unmarked skb. On the vulnerable 7.0.9 kernel the variant corrupts /usr/bin/su in the page cache and would yield root. On the fixed 7.0.10 kernel the variant is blocked: the stable backport includes both the CVE-2026-43503 multi-site fix and the CVE-2026-46300 skb_try_coalesce() fix, so the shared-frag marker is preserved and skb_cow_data() forces a copy before decryption. No bypass of the fixed kernel was found.
Fix Coverage / Assumptions
The CVE-2026-43503 patch (48f6a5356a33) restores the invariant:
An skb that references externally-owned or file-backed page-cache pages must have
SKBFL_SHARED_FRAGset.
It does so by OR-ing the source skb's SKBFL_SHARED_FRAG bit into the destination skb whenever one of the six audited helpers moves fragment descriptors:
__pskb_copy_fclone()skb_shift()skb_gro_receive()skb_gro_receive_list()tcp_clone_payload()skb_segment()
The patch assumes that these are the only frag-transfer sites that can carry page-cache-backed pages to an in-place writer, and that skb_copy() / skb_copy_expand() need no change because they linearize data into freshly allocated memory.
What the patch does not cover:
skb_try_coalesce()(fixed separately by CVE-2026-46300).skb_zerocopy()and related helpers (no known unprivileged exploit path to the ESP sink).- Any future kernel code that introduces a new fragment-transfer site without copying the marker.
Variant / Alternate Trigger
Candidate 1: Fragnesia / ESP-in-TCP / skb_try_coalesce() (tested)
- Entry point: Unprivileged user+network namespace; create a
vethpair, configure an XFRM transport-mode SA/SP for ESP-in-TCP, and splice a page-cache page of/usr/bin/suinto a TCP socket viavmsplice()/splice(). - Trigger path:
tcp_v4_rcv()→ TCP receive coalescing →skb_try_coalesce()moves shared frags into the ESP-in-TCP skb;espintcpreceive path callsskb_cow_data(), which checksskb_has_shared_frag(). - Sink: In-place AES-GCM/AES-CBC decryption over the file-backed page-cache page.
- Files/functions involved:
net/core/skbuff.c:skb_try_coalesce(),net/ipv4/espintcp.c,net/ipv4/tcp_input.c. - Result on v7.0.9:
RESULT: VULNERABLE (page cache modified)— the write primitive works. - Result on v7.0.10:
RESULT: NOT VULNERABLE (page cache unchanged)— the marker is preserved andskb_cow_data()makes a copy.
Candidate 2: Other CVE-2026-43503 helpers with different protocols (not tested separately)
The CVE-2026-43503 fix is applied at the function level, so any path through __pskb_copy_fclone(), skb_shift(), skb_gro_receive(), skb_gro_receive_list(), tcp_clone_payload(), or skb_segment() is covered regardless of the network protocol or driver. Additional protocol-specific triggers (IPv6 TEE, GRO on a different driver, TCP clone probes) are therefore not distinct bypasses; they reach the same now-fixed sink.
Candidate 3: skb_zerocopy() paths (ruled out by analysis)
skb_zerocopy() is used by XDP socket TX, Open vSwitch, and nfnetlink_queue. It creates fragment references without propagating SKBFL_SHARED_FRAG, but none of these consumers feed the resulting skb into the XFRM ESP input path under an unprivileged local trust boundary. No public exploit or reliable unprivileged trigger is known, so this remains a theoretical gap rather than a demonstrated bypass.
- Package/component affected: Linux kernel networking stack (
net/core/skbuff.c,net/core/gro.c,net/ipv4/tcp_output.c,net/ipv4/espintcp.c). - Affected versions as tested: Ubuntu mainline
7.0.9-070009-generic(vulnerable to both DirtyClone and Fragnesia); Ubuntu mainline7.0.10-070010-generic(blocked). - Risk level: Local privilege escalation. An unprivileged local user with user and network namespaces can gain root by overwriting the page-cache copy of a setuid binary. The variant is at least as severe as the original DirtyClone; it is blocked only because the tested fixed kernel includes the sibling CVE-2026-46300 patch.
Impact Parity
- Disclosed/claimed maximum impact: Local privilege escalation (
privilege_escalation) — arbitrary write into read-only page-cache pages of setuid binaries, leading to root code execution. - Reproduced impact from this variant run: Full privilege escalation on
7.0.9(the variant overwrites/usr/bin/suin the page cache). The impact was not reproduced on7.0.10because the write primitive was blocked. - Parity:
partial— the variant is a real, distinct trigger for the same root cause on the vulnerable kernel, but it is not a bypass of the fixed kernel tested. - Not demonstrated: Root shell on the fixed kernel; bypass of the combined CVE-2026-43503 + CVE-2026-46300 mitigation.
Root Cause
The same root cause underlies both DirtyClone and Fragnesia: the Linux kernel has multiple fragment-transfer helpers that move page references between skbs without moving the SKBFL_SHARED_FRAG metadata flag. When the destination skb reaches an in-place writer (XFRM ESP input), skb_has_shared_frag() returns false, skb_cow_data() is skipped, and decryption writes directly into file-backed page-cache memory.
The CVE-2026-43503 patch fixes six helpers. Fragnesia uses a seventh helper, skb_try_coalesce(), which was fixed by a separate commit. The two fixes are siblings; the tested 7.0.10 stable kernel includes both, so the variant is blocked.
Reproduction Steps
Run the variant reproduction script:
bash bundle/vuln_variant/reproduction_steps.shThe script is idempotent and will exit
1because the variant is blocked on the fixed kernel.The script performs the following:
- Builds a minimal initramfs that mounts the Fragnesia rootfs and
switch_roots into it. - Boots the v7.0.9 vulnerable kernel with the Fragnesia rootfs under QEMU.
- Boots the v7.0.10 fixed kernel with the Fragnesia rootfs under QEMU.
- Captures serial console output to
bundle/logs/qemu_fragnesia_vuln.logandbundle/logs/qemu_fragnesia_fixed.log. - Greps for
RESULT: VULNERABLEorRESULT: NOT VULNERABLEto determine whether the bypass succeeded.
- Builds a minimal initramfs that mounts the Fragnesia rootfs and
Expected evidence:
logs/qemu_fragnesia_vuln.logcontainsRESULT: VULNERABLE (page cache modified).logs/qemu_fragnesia_fixed.logcontainsRESULT: NOT VULNERABLE (page cache unchanged).
Evidence
- Vulnerable run log:
bundle/logs/qemu_fragnesia_vuln.log
Key excerpt:[+] RESULT: VULNERABLE (page cache modified) - Fixed run log:
bundle/logs/qemu_fragnesia_fixed.log
Key excerpt:[-] byte at index=24 unchanged after 8 attempts, kernel may be fixedfollowed by[*] RESULT: NOT VULNERABLE (page cache unchanged). - Runtime manifest:
bundle/vuln_variant/runtime_manifest.json - Validation verdict:
bundle/vuln_variant/validation_verdict.json - Patch analysis:
bundle/vuln_variant/patch_analysis.md - Environment: QEMU x86_64, Ubuntu mainline kernels
7.0.9-070009-genericand7.0.10-070010-generic, 512 MB RAM, 2 vCPUs.
Recommendations / Next Steps
Do not treat CVE-2026-43503 as a standalone fix. Distribution backports must include both:
- commit
48f6a5356a33(CVE-2026-43503, six helpers), and - the CVE-2026-46300
skb_try_coalesce()commit (Fragnesia).
A kernel with only the first commit is still vulnerable to Fragnesia.
- commit
Extend static review to any remaining frag-transfer helpers such as
skb_zerocopy()and future GRO/offload code. Even though no unprivileged trigger is known today, the same shape of bug could reappear.Consider a structural hardening patch that makes
SKBFL_SHARED_FRAGpropagation automatic whennr_fragsis increased by moving descriptors, rather than relying on authors to remember each site. This would close the regression window for future variants.Regression test: Add a kernel self-test that verifies
skb_has_shared_frag()is true after each of the seven known frag-transfer helpers when the source skb has the marker set.
Additional Notes
- Idempotency: The script was run three times; each run produced identical verdicts (
VULNERABLEon7.0.9,NOT VULNERABLEon7.0.10) and exited1. - Limitations: The Fragnesia binary is a prebuilt artifact from the project cache. This run treats it as an alternate trigger to test the completeness of the fix; it does not claim to have discovered a new kernel bug. No host-side files were modified; the rootfs images are mounted read-only inside QEMU.
- Trust boundary: The variant remains a local privilege escalation under the same trust model as the original CVE (unprivileged user/network namespace).
CVE-2026-43503 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
Unknown error
ls -la /data/pruva/project-cache/6cba72b6-b104-4ebf-be7b-01f748e87ccf{"cwd":"/data/pruva/runs/0a5d30f2-96f7-4243-8385-9ad0524e1fda","duration_ms":7,"exit_code":0,"stderr":"","stdout":"total 507388\ndrwxr-xr-x 1 vscode vscode 1370 Jul 3 10:05 .\ndrwxr-xr-x 1 vscode vscode 1894 Jul 3 04:50 ..\ndrwxr-xr-x 1 vscode vscode 22 Jul 2 21:46 .pruva\ndrwxr-xr-x 1 vscode vscode 6 Jul 3 09:21 bond-mod-stage\ndrwxr-xr-x 1 vscode vscode 6 Jul 3 09:39 bond-mod-stage-7rc2\ndrwxr-xr-x 1 vscode vscode 18 Jul 3 09:10 bond-mods\ndrwxr-xr-x 1 vscode vscode 18 Jul 3 09:29 bond-mods-7rc2\ndrwxr-xr-x 1 vscode vscode 210 Jul 3 09:11 bond-rootfs-\ndrwxr-xr-x 1 vscode vscode 210 Jul 3 09:21 bond-rootfs-base\ndrwxr-xr-x 1 vscode vscode 210 Jul 3 09:39 bond-rootfs-base-7rc2\ndrwxr-xr-x 1 vscode vscode 210 Jul 3 09:11 bond-rootfs-fixed\ndrwxr-xr-x 1 vscode vscode 210 Jul 3 09:39 bond-rootfs-fixed-7rc2\ndrwxr-xr-x 1 vscode vscode 210 Jul 3 09:29 bond-rootfs-probe-7rc2\ndrwxr-xr-x 1 vscode vscode 210 Jul 3 09:21 bond-rootfs-vuln\ndrwxr-xr-x 1 vscode vscode 210 Jul 3 09:39 bond-rootfs-vuln-7rc2\ndrwxr-xr-x 1 vscode vscode 210 Jul 3 09:39 bond-var-rootfs-fixed\ndrwxr-… [truncated]find /data/pruva/project-cache/6cba72b6-b104-4ebf-be7b-01f748e87ccf/.pruva -maxdepth 3 -type f -o -type l | head -50/data/pruva/project-cache/6cba72b6-b104-4ebf-be7b-01f748e87ccf/.pruva/proof-carry/latest_attempt/proof_carry_manifest.json /data/pruva/project-cache/6cba72b6-b104-4ebf-be7b-01f748e87ccf/.pruva/proof-carry/latest_confirmed/proof_carry_manifest.json
Artifacts and Evidence for CVE-2026-43503
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2026-43503
FAQ: CVE-2026-43503
How does the DirtyClone privilege escalation attack work?
skb_cow_data() copy-on-write safeguard. This lets esp_input() decrypt directly into the page-cache page of a root-owned setuid binary; by choosing the AES-CBC key/IV so the decrypted bytes are attacker-controlled shellcode, an unprivileged local attacker (able to create user and network namespaces) can rewrite a binary like /usr/bin/su in RAM and obtain a root shell when it is executed.How severe is CVE-2026-43503?
How can I reproduce CVE-2026-43503?
esp_input() to decrypt attacker-controlled shellcode into a setuid root binary's page-cache page, and demonstrates a root shell when that binary is executed.References for CVE-2026-43503
Authoritative sources for CVE-2026-43503 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.