flawopen.com/Incidents/Baron Samedit
A form-processing clerk has a rule: a backslash means "treat the next character literally". Someone hands in a form ending in a single backslash, so the clerk reaches for the next character — but there isn't one, because the form ended. Rather than stopping, they keep reading past the edge of the page and copying whatever they find onto the next form in the pile, overwriting it. Arrange the pile carefully and you can dictate exactly what the clerk writes.
In January 2021 Qualys disclosed CVE-2021-3156, nicknamed "Baron Samedit", a heap buffer overflow in sudo. It allowed any local user to become root — with no password, and regardless of whether that user appeared in the sudoers file at all. Exploitation worked in the default configuration.
Qualys demonstrated working root exploits on Ubuntu 20.04, Debian 10 and Fedora 33. Because sudo is installed essentially everywhere on Unix-like systems, the affected population was close to the entire Linux and macOS server estate.
The bug was introduced in a commit in July 2011 and went unnoticed for nearly a decade, affecting legacy versions 1.8.2 through 1.8.31p2 and stable versions 1.9.0 through 1.9.5p1.
sudo supports escaping special characters in command arguments with backslashes, and unescapes them later. Normally, when sudo runs a command in "shell" mode it escapes the arguments on the way in, so the unescaping logic never encounters a malformed string.
Invoking sudo through sudoedit -s reached the unescaping loop without the corresponding escaping step having run. That made it possible to pass an argument ending in a lone trailing backslash — a state the unescaping code had been written to assume could never occur.
On encountering a backslash, the loop consumed the following character. With the backslash as the final byte, the "following character" was the string's null terminator — so the loop stepped over the end of the string and carried on reading and copying out-of-bounds data into a heap buffer sized for the original input. The attacker controlled both the length and the content of the overflow.
/* Simplified illustration */ while (*from != '\0') { if (from[0] == '\\' && from[1] != '\0') from++; *to++ = *from++; } /* In the vulnerable path the guard on from[1] was not effective, so a trailing "\" consumed the NUL and the loop ran past the buffer end. */
/* 1. Never advance past a terminator. Check the next byte exists before consuming it. */ /* 2. Do not rely on an invariant established elsewhere. The unescaper assumed a caller had escaped the input. One code path did not, and the assumption was never checked locally. */
That second point is the durable engineering lesson. The unescaping function was correct given its assumed precondition. The vulnerability lived in the gap between a documented assumption and an unusual call path that violated it. Preconditions enforced by convention rather than by code fail silently, and they fail years later, when whoever knew the convention has moved on.
Privilege escalation flaws are sometimes discounted because they require existing access. That reasoning misreads how intrusions work. Attackers routinely obtain low-privilege access first — a compromised web application process, a stolen SSH key for an unprivileged account, a container breakout, a malicious dependency running in CI. A reliable local root exploit converts that foothold into total control of the host.
In shared environments the effect compounds: on a multi-user build server or a shell host, this bug meant every user was effectively root.
\0 fails the moment any path can step over one.No. That is what made this unusually severe — the overflow occurred during argument processing, before any authorisation decision. Users with no sudo rights whatsoever could exploit it.
This specific failure mode, yes — a bounds-checked language would panic or throw rather than write out of bounds, turning a root exploit into a crash. The logic error of mishandling a trailing escape could still exist; its consequences would be far less severe.