Safeguard
Vulnerability Analysis

Dirty Pipe (CVE-2022-0847) Explained: Overwriting Read-Only Files in the Linux Kernel

CVE-2022-0847, Dirty Pipe, let unprivileged users overwrite data in read-only files through an uninitialized pipe flag — a clean path to root. Here is the page-cache mechanism behind it.

Marcus Chen
Security Researcher
Updated 5 min read

CVE-2022-0847, nicknamed Dirty Pipe, is a Linux kernel vulnerability rated CVSS v3.1 7.8 (High) that let an unprivileged local user overwrite data in files they should only be able to read. That includes read-only files, files owned by root, and pages backing SUID binaries — which makes it a straightforward and reliable local privilege escalation. The name deliberately echoes 2016's Dirty COW, because both abuse the page cache to corrupt data an attacker has no write permission for.

Timeline and impact

Security researcher Max Kellermann discovered Dirty Pipe while investigating corrupted files in a customer's web logs, and disclosed it on March 7, 2022, with a clear proof of concept. The exploit was notable for how clean and deterministic it was: no race-condition flakiness, no memory-corruption fragility — just a few system calls that reliably wrote attacker data into a target file's page cache. Working root exploits (for example, overwriting /etc/passwd or hijacking a SUID binary) circulated immediately. Android devices running affected kernel versions were exposed too, broadening the impact well beyond servers.

Technical root cause

The bug is an uninitialized flag in the kernel's pipe machinery, introduced by a refactor that shipped in Linux 5.8.

Linux pipes are backed by pipe_buffer structures, each pointing at a page of data and carrying a set of flags. One flag, PIPE_BUF_FLAG_CAN_MERGE, tells the kernel that a new write may be appended into the existing page backing that buffer rather than requiring a fresh page. Separately, the splice() system call can attach a file's page-cache pages directly into a pipe without copying, for efficiency.

The refactor that added PIPE_BUF_FLAG_CAN_MERGE failed to initialize the flags field in the code paths that populate pipe buffers (copy_page_to_iter_pipe() and push_pipe()). As a result, a pipe buffer could inherit a stale CAN_MERGE flag from previous use. The exploit chains that oversight:

1. Create a pipe and fully fill it, so its buffers get CAN_MERGE set.
2. Drain the pipe completely (flag remains stale on the reused buffers).
3. splice() a target read-only file into the pipe at a chosen offset,
   attaching the file's page-cache pages to the pipe buffers.
4. write() attacker data to the pipe. Because CAN_MERGE is set,
   the kernel writes into the page-cache page backing the file.

The write lands in the file's cached pages in memory without any permission check on the file itself, corrupting its in-memory contents. Anything reading the file afterward sees the attacker's data. To escalate, an attacker overwrites a critical file — replacing a line in /etc/passwd to give a controlled account root, or patching a SUID root binary.

There are constraints that scope the primitive: the attacker cannot enlarge the file, cannot write across a page boundary in a single operation, and cannot modify the very first byte of a page (offset zero of a page can't be the merge target). None of these prevent the classic privilege-escalation exploits — they just shape the technique.

How to detect if you are affected

  • Check the kernel version. uname -r. The vulnerable window opened in 5.8 and closed with the fixes below. Kernels earlier than 5.8 predate the offending flag and are not affected by this specific bug.
  • Account for backports. Distributions maintain their own kernel version strings, so compare against your vendor's advisory rather than assuming the upstream number.
  • Include container hosts and node images. The kernel is shared by every container on a host, so a vulnerable node kernel exposes all workloads on it.

Because container images pin base userlands but run on a host kernel, tracking both matters. Safeguard's container security scanning and OS-level inventory help you see the kernel and package picture across your nodes.

Remediation and patched versions

  1. Upgrade the kernel to a fixed release: 5.16.11, 5.15.25, 5.10.102, or later, or your distribution's backported equivalent. Reboot into the patched kernel — a running system keeps the vulnerable code until it does.
  2. Rebuild and roll node images in Kubernetes and cloud fleets so new nodes come up patched, then cycle old nodes out.
  3. Audit for abuse on multi-tenant and internet-facing hosts: unexpected changes to /etc/passwd, modified SUID binaries, and anomalous local privilege gains predating your patch date.
  4. Re-verify the deployed kernel version everywhere after the rollout; stale nodes are the usual reason this finding resurfaces.

How Safeguard surfaces and auto-fixes Dirty Pipe

CVE-2022-0847 is a case where a moderate CVSS number hides an easy, reliable path to root, which is exactly why prioritization has to weigh reachability and exploit maturity rather than score alone. Safeguard inventories kernel and OS-package versions across hosts, node images, and CI runners, matching them against vulnerability intelligence so a lingering 5.8–5.15 kernel on a forgotten node is surfaced rather than assumed patched. Griffin AI correlates that finding with KEV and EPSS context and where the host sits in your environment, ranking a locally-reachable escalation on a multi-tenant box ahead of dormant issues.

Where the remediation is an image or base bump, automated fix pull requests update the affected image definitions so patched nodes roll out through your normal pipeline instead of a manual scramble. If you are evaluating how different tools handle OS- and kernel-layer findings versus application dependencies, our platform comparison covers the distinction. And because Dirty Pipe starts from "attacker already has a local shell," it pairs naturally with the container-hardening guidance in Safeguard's CLI workflow for shifting these checks left into the build.

A single uninitialized field turned a read-only file into a writable one. Continuous kernel and image inventory is what keeps that field from quietly living on in your fleet.

Register at app.safeguard.sh/register, or read the documentation at docs.safeguard.sh.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.