Overview
CVE-2022-0847, nicknamed "Dirty Pipe," is a local privilege escalation vulnerability in the Linux kernel's pipe subsystem. Discovered by Max Kellermann of CM4all while investigating production log file corruption, the flaw allows any unprivileged local user to overwrite the contents of read-only page-cache pages — including setuid binaries — and gain root access. A deterministic, race-condition-free exploit was released publicly on the same day as disclosure.
The vulnerability is conceptually related to Dirty COW (CVE-2016-5195) and is the direct historical predecessor to Copy Fail (CVE-2026-31431): all three exploit the same fundamental primitive — corrupting the kernel's page cache to modify files the attacker has no write permission to. Dirty Pipe improved on Dirty COW by eliminating the race condition; Copy Fail later demonstrated the same primitive via an entirely different kernel subsystem.
What Is the Linux Kernel?
The Linux kernel is the foundational software layer between hardware and user-space programs, running in every major Linux distribution, cloud instance, Android device, and container runtime. A local privilege escalation flaw in the kernel allows any unprivileged process — a restricted user account, a compromised web application, or code running inside a container — to obtain complete control of the host.
Affected Versions
The exploitable form of the bug requires PIPE_BUF_FLAG_CAN_MERGE, introduced in Linux 5.8 (August 2020). The underlying uninitialized-flags issue was introduced earlier (Linux 4.9, October 2016) but was not exploitable before 5.8. Kernels prior to 5.8 are not affected.
| Kernel Branch | Vulnerable Range | Fixed Version |
|---|---|---|
| 5.10.x (LTS) | 5.10.0 – 5.10.101 | 5.10.102 |
| 5.15.x (LTS) | 5.15.0 – 5.15.24 | 5.15.25 |
| 5.16.x | 5.16.0 – 5.16.10 | 5.16.11 |
| < 5.8 | Not exploitable | — |
Fixes were released February 23, 2022 — twelve days before public disclosure. RHEL 8's 4.18-based kernel predates PIPE_BUF_FLAG_CAN_MERGE and is not exploitable via the known attack path.
Technical Details
Root Cause: Uninitialized pipe_buffer.flags
The Linux pipe subsystem manages a ring buffer of struct pipe_buffer slots, each holding a reference to a memory page and a flags field. In August 2020, commit f6dd975583bd (pipe: merge anon_pipe_buf*_ops) introduced PIPE_BUF_FLAG_CAN_MERGE: when set, the kernel writes subsequent data directly into the existing backing page rather than allocating a new one — a performance optimization for pipe-to-pipe data movement.
The bug is in two functions — copy_page_to_iter_pipe() and push_pipe() — which create pipe buffers backed by page-cache pages via splice(), but never initialize pipe_buffer.flags. A recycled ring-buffer slot retains whatever flags value a prior write left behind. If the prior write set PIPE_BUF_FLAG_CAN_MERGE, and the slot is then reused to hold a reference to a read-only file's page-cache page, the kernel treats that page-cache page as a valid write target.
Exploitation: Step by Step
- Create a pipe. Write enough data to fill all ring-buffer slots, setting every slot's flags to
PIPE_BUF_FLAG_CAN_MERGE. - Drain the pipe. Slots are empty but the poisoned flags value remains in each slot.
- Open the target file read-only. Only
O_RDONLYis required — no write permission to the target file is needed. - Call
splice()to read from the target file at the desired offset into the pipe's write end.copy_page_to_iter_pipe()places a reference to the target file's page-cache page into a ring-buffer slot without re-initializingflags— the poisonedPIPE_BUF_FLAG_CAN_MERGEpersists. - Write attacker data to the pipe. The kernel sees
PIPE_BUF_FLAG_CAN_MERGEand writes directly into the page-cache page of the read-only file. - The file's in-memory representation is now modified with attacker-controlled bytes. Reading or executing the file returns the corrupted content.
Privilege escalation path: Overwrite bytes within a setuid root binary (e.g., /usr/bin/su) to redirect execution to attacker shellcode, then invoke the binary to obtain a root shell.
Constraints
- The
splice()offset cannot land on a 4 KiB page boundary (must skip at least one byte into a page). - The write cannot span a page boundary.
- The file cannot be extended beyond its existing size.
- The first byte of the file cannot be targeted (offset must be ≥ 1 byte into a page).
Within those constraints, any byte range in any readable, page-cache-backed file is writable by an unprivileged user.
Attack Characteristics
| Attribute | Detail |
|---|---|
| Attack Vector | Local — requires an existing unprivileged user session |
| Privileges Required | Low — any user account suffices |
| Race Condition Required | No — fully deterministic |
| Write Permission Required | None — O_RDONLY access to the target file is sufficient |
| Forensic Detectability | Low — no on-disk modification; corruption is page-cache-only and disappears on reboot |
| Container Impact | Yes — unprivileged container processes can escalate to host root |
Page-Cache Exploit Lineage
Dirty Pipe belongs to a lineage of Linux kernel page-cache exploitation techniques that spans a decade:
| CVE | Name | Year | Mechanism | Race Required |
|---|---|---|---|---|
| CVE-2016-5195 | Dirty COW | 2016 | Race condition in copy-on-write path overwrites read-only mmap pages |
Yes — notoriously unstable |
| CVE-2022-0847 | Dirty Pipe | 2022 | Uninitialized pipe flag permits direct write to spliced page-cache page | No — deterministic |
| CVE-2026-31431 | Copy Fail | 2026 | AEAD crypto socket scratch write lands in page-cache page via algif_aead |
No — deterministic |
Discovery
Max Kellermann of CM4all GmbH (part of IONOS SE) discovered the vulnerability while investigating mysterious file corruption on a production log server. Over three months in 2021, 37 compressed log files developed incorrect CRC checksums, with corruption always starting at the PK (ZIP) magic bytes — a pattern that implicated an unrelated process writing into the kernel's page cache of files it had no business touching. After months of investigation, developing minimal reproducers, and eliminating all application-level causes, Kellermann confirmed on February 19, 2022 that the corruption was caused by a kernel bug. He reported it to the Linux security team the next day, providing both a patch and a working PoC. The investigation was initiated by a support ticket filed April 29, 2021 — nearly 10 months before the root cause was identified.
Exploitation Context
A working public exploit was released on the same day as public disclosure (March 7, 2022), immediately available to all threat actors.
- Tested platforms: Ubuntu 20.04 LTS (HWE kernel), Ubuntu 21.10, Debian 11, Android Pixel 6 (confirmed by Google Project Zero)
- Android impact: Pixel 6 running Linux 5.10 confirmed vulnerable; patched in the March 2022 Android Security Bulletin
- Container impact: Any containerized process can create pipes — effectively every container workload — making container-to-host escalation straightforward
- Kubernetes exposure: Kubernetes disables seccomp by default, leaving workloads fully exposed on affected kernel versions
- RHEL 8: The 4.18-based RHEL 8 kernel predates
PIPE_BUF_FLAG_CAN_MERGE; the latent uninitialized-flags bug is present but not exploitable via the known Dirty Pipe attack path
CISA added Dirty Pipe to the KEV catalog on April 25, 2022, confirming in-the-wild exploitation.
Remediation
Recommended Actions
-
Update the kernel to a fixed version: Linux 5.16.11, 5.15.25, or 5.10.102 (or any later release). Verify with
uname -r. -
Apply distribution vendor errata:
- Ubuntu: USN-5317-1 (Ubuntu 21.10, 22.04 beta; HWE kernels on 20.04)
- RHEL 9: RHSA-2022:0825 / RHSA-2022:0819
- Debian 11: DSA-5095-1
-
Confirm RHEL 8 is safe — check
uname -rreturns a 4.18-based kernel. RHEL 8 does not backportPIPE_BUF_FLAG_CAN_MERGEand is not vulnerable to the known Dirty Pipe exploit. -
Container environments: There is no practical per-container mitigation — the attack uses only standard pipe and splice syscalls available in every container. The only reliable mitigation is patching the host kernel.
-
Harden the kernel baseline: Dirty Pipe is one vulnerability in an ongoing class of page-cache exploitation techniques. For a systematic defense-in-depth approach, see Hardening the Linux Kernel: Defense in Depth Against Privilege Escalation.
Key Details
| Property | Value |
|---|---|
| CVE ID | CVE-2022-0847 |
| Vendor / Product | Linux — Kernel |
| NVD Published | 2022-03-10 |
| NVD Last Modified | 2025-11-06 |
| CVSS 3.1 Score | 7.8 |
| CVSS 3.1 Vector | CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| Severity | HIGH |
| CWE | CWE-665 — Improper Initialization |
| CISA KEV Added | 2022-04-25 |
| CISA KEV Deadline | 2022-05-16 |
| Known Ransomware Use | No |
CVSS 3.1 Breakdown
Required Action
Timeline
| Date | Event |
|---|---|
| 2021-04-29 | First corrupt log file support ticket filed at CM4all; investigation begins |
| 2022-02-19 | Max Kellermann confirms file corruption is a Linux kernel bug |
| 2022-02-20 | Vulnerability reported to Linux kernel security team; patch and PoC delivered |
| 2022-02-23 | Fixed stable releases published: Linux 5.16.11, 5.15.25, 5.10.102 |
| 2022-03-07 | Public disclosure by Kellermann; CVE-2022-0847 assigned; PoC released |
| 2022-03-10 | CVE-2022-0847 published in NVD |
| 2022-04-25 | Added to CISA Known Exploited Vulnerabilities catalog |
| 2022-05-16 | CISA BOD 22-01 remediation deadline |
References
| Resource | Type |
|---|---|
| NVD — CVE-2022-0847 | Vulnerability Database |
| CISA KEV Catalog Entry | US Government |
| The Dirty Pipe Vulnerability — Max Kellermann (Original Disclosure) | Security Research |
| Linux Kernel Fix Commit 9d2231c5 — Initialize pipe_buffer.flags to zero | Patch / Source Code |
| Bug-Introducing Commit f6dd9755 — pipe: merge anon_pipe_buf*_ops (introduced PIPE_BUF_FLAG_CAN_MERGE) | Patch / Source Code |
| CVE-2022-0847-DirtyPipe-Exploits — Public PoC (AlexisAhmed) | Security Research |
| Red Hat Security Bulletin RHSB-2022-002 — Dirty Pipe | Vendor Advisory |
| CWE-665 — Improper Initialization | Weakness Classification |