Overview

CVE-2021-3156, dubbed “Baron Samedit” by the Qualys Research Team who discovered it, is a heap-based buffer overflow vulnerability in sudo. It has been present in sudo since July 2011 (commit 8255ed69) and affects all default configurations of sudo versions 1.8.2 through 1.9.5p1.

Any local user - not just those listed in sudoers - can exploit this vulnerability to gain root privileges without requiring a password. That makes it one of the most impactful local privilege escalation vulnerabilities in recent Linux history.

Affected Versions

  • sudo 1.8.2 through 1.8.31p2 (legacy versions)
  • sudo 1.9.0 through 1.9.5p1 (stable versions)

This covers nearly every Linux distribution shipping sudo during that period:

  • Ubuntu 20.04 (Focal Fossa) - sudo 1.8.31
  • Debian 10 (Buster) - sudo 1.8.27
  • Fedora 33 - sudo 1.9.5p1
  • CentOS 7/8 - sudo 1.8.23/1.8.29

The Vulnerability

The bug is in the set_cmnd() function in sudo, specifically in how it handles the -s (shell) and -i (login) flags when combined with backslash-escaped characters.

When sudo is invoked in shell mode (sudoedit -s or sudo -s), it expects command arguments to be escaped with backslashes. The code in set_cmnd() walks through the arguments, removing escape characters and concatenating them into a single command string. The relevant logic does two things:

  1. Calculates the required buffer size by counting characters, skipping backslashes that precede other characters
  2. Copies the arguments into a heap-allocated buffer, again skipping escape backslashes

The problem is a mismatch between the size calculation and the copy operation. When an argument ends with a single unescaped backslash, the size calculation and the copy loop handle the trailing backslash differently. The copy loop reads past the end of the last argument into the next argument’s memory, writing characters into the heap buffer beyond its allocated size.

In pseudocode, the vulnerable logic looks like this:

// Size calculation (simplified)
for (each argument) {
    for (each char in argument) {
        if (char == '\\' && next_char != '\0')
            skip;  // count next char, not the backslash
        size++;
    }
}

// Buffer copy (simplified)
for (each argument) {
    for (each char in argument) {
        if (char == '\\' && next_char != '\0')
            skip;  // copy next char, not the backslash
        *buf++ = char;
    }
}

The key insight is next_char != '\0'. At the end of an argument string, the null terminator stops the backslash escaping logic. But the arguments in sudo’s memory are laid out contiguously (as they come from argv), so after the null terminator of one argument comes the next argument. The copy loop can be tricked into continuing past the null terminator boundary.

Triggering the Bug

The vulnerability is triggered by invoking sudoedit with the -s flag and an argument that ends with a single backslash:

sudoedit -s '\' $(python3 -c 'print("A" * 65536)')

Under normal circumstances, sudoedit checks whether the invoking user is authorized before executing. However, the vulnerable code path in set_cmnd() is reached before the authorization check. This means any local user can trigger the overflow regardless of sudoers configuration.

You can test if a system is vulnerable without exploitation:

sudoedit -s /

If the system is vulnerable, this returns an error starting with sudoedit:. If patched, it returns a usage message starting with usage:.

Exploitation

Qualys developed working exploits for Ubuntu 20.04, Debian 10, and Fedora 33. The exploitation technique varies by distribution due to differences in heap layout, allocator behavior, and ASLR implementation.

The general approach involves:

  1. Crafting the argument list to produce a controlled heap overflow
  2. Using the overflow to corrupt adjacent heap metadata or application data structures
  3. Leveraging the corruption to achieve code execution as root

The heap-based nature of the vulnerability means exploitation requires careful heap grooming. The attacker needs to arrange heap allocations so that the overflowed buffer is adjacent to a target object whose corruption leads to controlled writes or code execution.

Qualys chose different exploitation strategies per target:

  • On Ubuntu, they targeted nss_load_library() by overwriting a service_user struct to load an attacker-controlled shared library
  • On Debian, a similar approach targeting nss_load_library() was used with adjusted offsets
  • On Fedora, the exploitation targeted a different heap structure due to glibc version differences

In all cases, the end result is arbitrary code execution as root.

Detection

Check sudo version:

sudo --version

Any version below 1.9.5p2 in the stable branch or below 1.8.32 in the legacy branch is potentially vulnerable.

Quick vulnerability test:

sudoedit -s /
  • Vulnerable: returns sudoedit: /: not a regular file
  • Patched: returns usage: sudoedit [...]

Log-based detection:

Exploitation attempts may appear in auth logs (/var/log/auth.log or /var/log/secure) as sudoedit invocations with unusual arguments. Look for:

grep sudoedit /var/log/auth.log | grep -E '\\\\$'

However, a skilled attacker may not leave clear log traces, especially if they clean up after gaining root.

Patching and Mitigation

Patch immediately. This is a local privilege escalation that works against default sudo configurations. Every user-accessible Linux system should be updated.

# Ubuntu/Debian
sudo apt update && sudo apt install sudo

# RHEL/CentOS
sudo yum update sudo

# Fedora
sudo dnf update sudo

After updating, verify the fix:

sudoedit -s /
# Should return "usage:" message

If patching is not immediately possible:

The Qualys advisory suggests enabling Defaults noexec in sudoers as a partial mitigation, but this only makes exploitation harder, not impossible. It prevents the nss_load_library() attack vector but does not address the underlying overflow.

There is no complete workaround short of patching. The vulnerability is in sudo’s argument parsing, which executes before any sudoers policy is evaluated.

Timeline

  • July 2011 - Vulnerable code introduced in sudo commit 8255ed69
  • January 13, 2021 - Qualys discovers the vulnerability
  • January 19, 2021 - Qualys reports to sudo maintainer Todd C. Miller
  • January 26, 2021 - Coordinated public disclosure and patches released (sudo 1.9.5p2)
  • January 26, 2021 - CVE-2021-3156 assigned
  • January 27, 2021 - Distribution patches begin rolling out

Impact Assessment

The severity of Baron Samedit is high for several reasons:

  • It affects the default configuration of sudo - no special sudoers setup required
  • Any local user can exploit it, not just users with sudo privileges
  • It has existed for nearly 10 years before discovery
  • Working exploits were developed for major distributions
  • sudo is installed on virtually every Unix-like system

CVSS 3.1 base score: 7.8 (High) - AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

The “Local” attack vector keeps it from being Critical, but in practice, any system where an attacker has a low-privilege shell (through SSH, a compromised web application, or a container escape) is at risk. In cloud environments where multiple users share a system, this is especially concerning.

Lessons

This vulnerability is a textbook example of why C string handling is dangerous and why even well-audited security-critical software can harbor decade-old bugs. The mismatch between the size calculation and the copy operation is subtle. It only manifests with a specific input pattern (trailing backslash) in a specific mode (shell mode via -s).

For defenders, the takeaway is clear: patch management is not optional. A local privilege escalation in sudo is the kind of vulnerability that turns a low-value foothold into full system compromise.