Description
On March 7, 2022, CM4all security researcher Max Kellermann published technical details on CVE-2022-0847, an arbitrary file overwrite vulnerability in versions 5.8+ of the Linux kernel. Nicknamed “Dirty Pipe,” the vulnerability arises from incorrect Unix pipe handling, where unprivileged processes can corrupt read-only files. Successful exploitation allows local attackers to escalate privileges by modifying or overwriting typically inaccessible files — potentially including root passwords and SUID binaries. Security researchers have also demonstrated that in some cases, public exploit code can be used to escape containers in that files modified inside the container also get modified on the host
Public exploit code is available as of March 7, 2022. Linux distributions have been notified and as of March 9, patches are still trickling out.
Affected products
Linux kernel versions since 5.8
Technical analysis
PoC
In this example test is a basic text file containing the contents Hello, world!. The permissions are changed to readable only, and the owner is set to root.
msf@dirtypipe:~$ ls -al test
-r--r--r-- 1 root root 14 Mar 9 11:52 test
msf@dirtypipe:~$ cat test
Hello, world!The original PoC takes three arguments: the target file to overwrite, the offset within the file to start writing at, and the data to write to the target file. Because some data from the target file has to be spliced first, the offset cannot start at 0, and the amount of data that is written cannot exceed a page boundary (4096 bytes). The attacker must have read permissions on the target file.
msf@dirtypipe:~$ uname -a
Linux dirtypipe 5.11.0-49-generic #55-Ubuntu SMP Wed Jan 12 17:36:34 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
msf@dirtypipe:~$ ./poc test 1 "ello, root!"
It worked!
msf@dirtypipe:~$ cat test
Hello, root!!While this shows a seemingly innocuous file write, a similar approach can be used to escalate privileges to root.
Another PoC demonstrates that the vulnerability can be used to overwrite an SUID binary to elevate privileges.
Patch
The patch appears to simply initialize the struct pipe_buffer flags, which removes the ability to arbitrarily set the PIPE_BUF_FLAG_CAN_MERGE flag.
[diff](https://lore.kernel.org/lkml/[email protected]/#iZ31lib:iov_iter.c) --git a/lib/iov_iter.c b/lib/iov_iter.c
index b0e0acdf96c1..6dd5330f7a99 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c @@ -414,6 +414,7 @@ static size_t copy_page_to_iter_pipe(struct page *page, size_t offset, size_t by
return 0;
buf->ops = &page_cache_pipe_buf_ops;
+ buf->flags = 0;
get_page(page);
buf->page = page;
buf->offset = offset;
@@ -577,6 +578,7 @@ static size_t push_pipe(struct iov_iter *i, size_t size,
break;
buf->ops = &default_pipe_buf_ops;
+ buf->flags = 0;
buf->page = page;
buf->offset = 0;
buf->len = min_t(ssize_t, left, PAGE_SIZE);
--IOCs
While exploitation is mostly memory-based, variants of the PoC overwrite ubiquitous SUID binaries on Linux, which means it’s possible that an attacker may leave behind corrupted system files or binaries.
Mitigation guidance
Patch and reboot systems as updates become available.



