GHSA-HQF9-8XV5-X8XW

regreSSHion: The Return of the Signal Handler Nightmare

Amit Schendel
Amit Schendel
Senior Security Researcher

Jan 5, 2026·5 min read

Executive Summary (TL;DR)

OpenSSH's sshd server contains a race condition in its signal handling logic. If a client does not authenticate within `LoginGraceTime`, a SIGALRM is triggered. The signal handler unsafely calls `syslog()`, which is not async-signal-safe. This can interrupt the heap manager in an inconsistent state, leading to heap corruption and eventual RCE as root. Attack complexity is high, but the impact is critical.

A signal handler race condition in OpenSSH's sshd server allows unauthenticated remote code execution (RCE) as root on glibc-based Linux systems. This is a regression of a vulnerability previously patched in 2006.

The Hook: A Blast from the Past

It’s not often we get to say 'I told you so' about a bug from 2006, but here we are. OpenSSH, the absolute bedrock of internet infrastructure, has tripped over its own shoelaces. Again.

Meet regreSSHion (CVE-2024-6387). It’s a signal handler race condition in sshd that allows unauthenticated remote code execution (RCE) with root privileges. If that sounds familiar, it's because this is effectively a regression of CVE-2006-5051. Someone, somewhere, refactored some code and accidentally invited an old ghost back into the machine.

Why should you care? Because sshd is exposed to the internet on millions of servers. It is the front door. And right now, the lock on that door has a microscopic fracture that, if hit with a sledgehammer 10,000 times at the exact right microsecond, causes the door to dissolve.

The Flaw: Async-Signal-Safety 101

Here is the golden rule of Unix systems programming: Do not do complex things inside a signal handler.

When a signal (like SIGALRM) fires, the OS pauses whatever the CPU was doing to run the handler. If the main program was in the middle of a malloc() or free() call (manipulating the heap), and the signal handler also tries to allocate memory (via syslog()), you get a reentrancy problem. The heap metadata is in an inconsistent state. The handler corrupts it. Game over.

In sshd, there is a LoginGraceTime setting (default 120 seconds). If you don't log in by then, sshd gets impatient. It raises a SIGALRM. The handler for this signal, sigdie(), decides to be helpful and log a message via syslog().

[!WARNING] syslog() is NOT async-signal-safe. It uses malloc(). Calling it inside a signal handler is like trying to change a tire while the car is moving at 60mph.

The Code: The Smoking Gun

Let's look at the crime scene. The vulnerability exists in the signal handler logic located in sshd.c.

Here is the simplified logic flow that dooms the process:

// The Signal Handler
void sigdie(int sig) {
    // ... various cleanup ...
    
    // THE BUG: calling syslog() inside a handler
    syslog(LOG_INFO, "Timeout before authentication for %s", client_addr);
    
    _exit(1);
}

When SIGALRM fires, execution jumps here. If the main thread was currently inside a glibc memory function (like malloc or free handling public key exchange data), syslog will try to grab the same heap lock or manipulate the same linked list pointers.

This results in heap corruption. The fix is simple but annoying: don't use syslog in the handler. Use a safe primitive or just _exit().

The Exploit: Winning the Race

Exploiting this is not like a standard buffer overflow where you send a long string and win. This is a race condition. We are playing a probabilistic game against the scheduler.

The Strategy:

  1. Connection Flood: We open exactly MaxStartups connections to the server.
  2. Timing: We perform the SSH handshake but stall just before authentication.
  3. The Trigger: We wait for LoginGraceTime (120s) to expire.
  4. The Collision: We need the SIGALRM to interrupt the main thread precisely when it is manipulating the heap (e.g., parsing a massive public key packet we sent).

If we time it right, the heap state is corrupted. By carefully grooming the heap beforehand (Heap Feng Shui), we can turn this corruption into an overwrite of a glibc structure (like _IO_2_1_stdout_ or dtors).

From there, it's standard ROP (Return Oriented Programming) to bypass ASLR (Address Space Layout Randomization) and land a shell. Note: This takes on average ~10,000 attempts on a 32-bit system, and significantly more on 64-bit due to ASLR entropy. It's noisy, but it works.

The Impact: Root for Everyone

If an attacker wins the race, they execute code as the user running sshd. In most default configurations, that user is root.

  • Privilege Level: Root / System Administrator.
  • Authentication: None required.
  • Detection: High. The exploit requires thousands of connections, filling logs with "Timeout" errors—ironically, the very log message causing the crash is what alerts the SOC.

While the race is hard to win (taking hours or days), the payoff is total system compromise. This is a critical risk for high-value targets where an attacker can afford to be noisy.

The Mitigation: Stop the Bleeding

First, check your version. OpenSSH versions 8.5p1 through 9.7p1 are vulnerable.

Immediate Fix: Upgrade to OpenSSH 9.8p1. The developers removed the unsafe syslog call from the signal handler.

Workaround (If you can't patch): Set LoginGraceTime to 0 in your sshd_config.

# /etc/ssh/sshd_config
LoginGraceTime 0

[!NOTE] This disables the timer entirely. This prevents the signal from ever firing, neutralizing the bug. However, it exposes you to a Denial of Service (DoS) where attackers use up all your connection slots by holding them open indefinitely. Pick your poison: RCE or DoS.

Fix Analysis (1)

Technical Appendix

CVSS Score
8.1/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
0.04%
Top 100% most exploited
14,000,000
via Shodan

Affected Systems

OpenSSH 8.5p1 through 9.7p1glibc-based Linux systems

Affected Versions Detail

Product
Affected Versions
Fixed Version
OpenSSH
OpenBSD
>= 8.5p1, < 9.8p19.8p1
AttributeDetail
CWE IDCWE-364
Attack VectorNetwork
CVSS v3.18.1 (High)
ImpactUnauthenticated RCE (Root)
Exploit StatusPoC Available / High Complexity
Root CauseSignal Handler Race Condition
CWE-364
Signal Handler Race Condition

Signal Handler Race Condition

Vulnerability Timeline

Vulnerability Publicly Disclosed by Qualys
2024-07-01
OpenSSH 9.8p1 Released
2024-07-01
Added to CISA KEV
2024-07-08

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.