
Educational, defensive kit for two Linux page-cache-corruption LPEs (DirtyClone CVE-2026-43503, pedit COW CVE-2026-46331): hardening, detection, verification, seccomp + validation harness. Detection and prevention only — no exploit code. TLP:CLEAR.
Detect, contain, and verify defenses against two Linux page-cache-corruption local privilege escalations — DirtyClone (CVE-2026-43503) and pedit COW (CVE-2026-46331) — on hosts and containers.
This is an educational, defensive security kit. It explains how both vulnerabilities work at the syscall level and ships hardening, detection, verification, and seccomp tooling — plus a validation harness that proves the tooling works on real kernels. It contains no exploit, shellcode, or target offsets, by design.
Both CVEs let an unprivileged local user become root by corrupting the page cache (the RAM
copy) of a setuid-root binary such as /usr/bin/su — without ever touching the file on disk. That
makes them stealthy: file-integrity monitoring stays green, disk forensics find nothing, and the
corruption clears on reboot.
Patching the kernel is the real fix. But during the rollout window — and as defense-in-depth afterward — you need to close the attack paths, watch for the attack chain, and verify your posture. That is what this kit provides, with every control mapped back to a documented step of the exploit chain so you can see why it works.
Both bugs are the same defect class: the kernel writes to a buffer it believes is private while that buffer is still backed by shared, file-backed page-cache memory. Two structural gates govern every variant of both chains:
Fixed upstream in stable point-releases (DirtyClone ≥ 6.12.91 / 7.0.10; pedit COW 6.12.94 / 7.0.13) plus vendor backports; mainline 7.1 is final. Confirm your kernel against your distro's tracker — see docs/analysis.md §8.
Linux hosts only. These scripts read and write real kernel state. Run hardening on a host you control; run the destructive validation harness on a disposable VM. See Requirements.
# 1. Preview the host containment changes (writes nothing)
sudo ./kit/harden-pagecache-lpe.sh --dry-run
# 2. Apply userns restrictions + vulnerable-module blocks
sudo ./kit/harden-pagecache-lpe.sh
# 3. Verify posture — run the functional probe as an UNPRIVILEGED user
sudo -u nobody ./kit/verify-pagecache-lpe.sh # exit: 0=PASS 1=WARN 2=FAIL
# 4. (Optional) Watch the attack chain live with eBPF
sudo bpftrace ./kit/detect-pagecache-lpe.bt
For containers, apply the seccomp overlay
(kit/seccomp-pagecache-lpe.json):
docker run --security-opt seccomp=kit/seccomp-pagecache-lpe.json <image>
New here? Read START-HERE.md — a guided, lecture-style walkthrough from
the root cause to a full validation run.
.
├── START-HERE.md Guided walkthrough — the recommended entry point
├── docs/ The "why": analysis and operator guidance
│ ├── analysis.md Root-cause analysis, attack chains, detection engineering
│ ├── HARDENING-GUIDE.md Operator containment guide (host → systemd → Docker → Kubernetes)
│ └── plain-language-summary.md Gentler, plain-English overview of both bugs
├── kit/ The "what you run": four self-contained artifacts
│ ├── harden-pagecache-lpe.sh Apply host containment (sysctl + module blocks)
│ ├── verify-pagecache-lpe.sh Read-only posture check (PASS/WARN/FAIL)
│ ├── detect-pagecache-lpe.bt bpftrace/eBPF telemetry for the staging chain
│ └── seccomp-pagecache-lpe.json Container seccomp overlay denying the chain's syscalls
└── testkit/ The "proof": validation harness + SHOWCASE.md writeup
harden, verify): a Linux host with bash, sysctl, modprobe,
and unshare. Root for hardening; run the verify probe as a non-root user.detect-pagecache-lpe.bt): root, bpftrace ≥ 0.16, and kernel BTF
(/sys/kernel/btf/vmlinux). Some kprobes may be inlined on a given kernel — the script's header
explains how to adapt.testkit/): a disposable Linux VM — it writes real config and unloads
kernel modules. The EC2 launcher needs the AWS CLI v2 and jq; no SSH is used (transport is AWS
SSM). macOS users can run the local Docker smoke test, but full validation requires Linux.TLP:CLEAR — public, unrestricted distribution. This repository is detection and prevention only. It deliberately includes:
…and deliberately excludes:
The honest limits of this approach — what the validation does and does not prove — are documented in
testkit/SHOWCASE.md §8. Use only on systems you own or are authorized to
test. Hardening is containment, not a cure: patch your kernel.
START-HERE.md — the guided walkthrough (start here)docs/analysis.md — the full technical analysisdocs/plain-language-summary.md — a
gentler, plain-English overviewIssues and pull requests are welcome — see CONTRIBUTING.md. Because the controls
are mirrored across several files (the module list, the userns knobs, the detection bitmap), please
read the sync invariants in that guide before changing the attack surface.
Licensed under the Apache License 2.0.
| Gate | What it is | Strength as a control |
|---|
| 1. Capability path | CAP_NET_ADMIN obtained via unprivileged user namespaces (unshare(CLONE_NEWUSER|CLONE_NEWNET)) | Robust chokepoint — every variant must pass here, known and unknown. Close it first. |
| 2. Module surface | Vulnerable modules: act_pedit, esp4/esp6, rxrpc, xt_TEE, nf_dup_ipv4/nf_dup_ipv6 | Defense-in-depth — removes known primitives only; a novel sink would bypass it. |
| Component | Role |
|---|
docs/analysis.md | Source of truth: root cause, behavioral attack chains, detection engineering, hardening, comparative table. |
docs/HARDENING-GUIDE.md | Layered containment for hosts, systemd units, Docker/Podman, and Kubernetes. |
kit/ | The four deliverables. Copy this directory to a host to defend it. |
testkit/ | Reproducible validation on real kernels (local Docker + disposable EC2), and SHOWCASE.md — an honest assessment of what the tests do and don't prove. |