regreSSHion: The Return of the Signal Handler Nightmare
Jan 6, 2026·5 min read
Executive Summary (TL;DR)
OpenSSH server (sshd) contains a race condition in its signal handling logic. By winning a race against the `LoginGraceTime` timer, an unauthenticated attacker can interrupt the heap manager in an inconsistent state, leading to heap corruption and eventual Remote Code Execution (RCE) as root. It affects default configurations of OpenSSH versions 8.5p1 through 9.7p1 on glibc-based Linux systems.
A signal handler race condition in OpenSSH's sshd allows unauthenticated remote code execution (RCE) as root on glibc-based Linux systems. This is a regression of a vulnerability originally fixed in 2006 (CVE-2006-5051).
The Hook: Time is a Flat Circle
If you've been in this industry long enough, you start to see the same ghosts haunting the same hallways. In 2006, Mark Dowd discovered a signal handler race condition in OpenSSH (CVE-2006-5051). It was patched, we all applauded, and we moved on. Fast forward to 2024, and the Qualys Threat Research Unit has found that we somehow managed to un-fix it.
Meet regreSSHion (CVE-2024-6387). It is essentially the same bug class, reintroduced into OpenSSH version 8.5p1 nearly four years ago. The vulnerability lies in sshd, the ubiquitous daemon that likely secures the very server you are using to read this.
The premise is simple yet terrifying: an unauthenticated attacker can exploit a race condition in the signal handler to corrupt the heap and execute arbitrary code as root. Yes, that root. No credentials required, just network access and a lot of patience.
The Flaw: Async-Signal-Safety (Or Lack Thereof)
The root cause here is a violation of one of the golden rules of systems programming: never call async-signal-unsafe functions inside a signal handler.
When sshd receives a connection, it sets a timer via SIGALRM defined by LoginGraceTime (usually 120 seconds). If you don't authenticate within that window, the alarm fires, the signal handler catches it, and it kills the connection. Simple, right?
The problem arises when the signal handler decides to perform logging. In the affected versions, the handler calls syslog(). The syslog() function is not async-signal-safe. Why? Because strictly speaking, syslog() often internally calls malloc() or free() to manage message buffers.
If the signal interrupts the main execution flow while the program is already inside malloc() or free() (manipulating the heap), and then the signal handler calls syslog() (which calls malloc() again), you get re-entrancy into the heap allocator. The allocator's internal structures (like the arena locks or free lists) are left in an inconsistent state, leading to heap corruption. It’s like trying to reorganize a library, and halfway through, someone pauses time, moves the shelves around, and tells you to keep working.
The Code: The Smoking Gun
Let's look at where the logic failed. The regression was introduced in October 2020 (OpenSSH 8.5p1) when the logging logic was refactored.
In the vulnerable code, the SIGALRM handler eventually routes to a function that looks something like this (simplified):
// Inside the signal handler context
void grace_alarm_handler(int sig) {
// ... setup context ...
// FATAL ERROR: syslog is NOT async-signal-safe
syslog(LOG_CRIT, "Timeout before authentication for %s", user);
_exit(1);
}The fix is technically simple but architecturally strict: do not perform complex operations in the handler. The patch moves the logging logic out of the async-signal context or ensures only safe primitives are used.
[!NOTE] In the patched version (9.8p1), the logic was altered to avoid the unsafe
syslogcall entirely during the async signal handling, restoring the safety guarantees present in versions prior to 8.5p1.
The Exploit: Grooming the Heap
Exploiting this is not a "point-and-click" adventure; it's a statistical war of attrition. To trigger the corruption, the attacker must disconnect strictly when sshd is in the middle of a heap operation (like processing a public key).
-
Heap Feng Shui: The attacker sends specific payloads (public keys) to fragment the heap and groom it into a predictable layout.
-
The Race: The attacker initiates a connection and waits for the
LoginGraceTimeto expire. The goal is to have theSIGALRMinterrupt the code execution exactly whensshdis inside afree()call handling the cleanup of a previous packet. -
The Corruption: If timed perfectly, the
syslog()call inside the handler invokesmalloc(), which tries to use the heap structures thatfree()was currently modifying. This allows the attacker to overwrite glibc'stcacheor fastbin chunks. -
ASLR Bypass: Since modern Linux uses Address Space Layout Randomization (ASLR), the attacker doesn't know where the heap or libc is. However, because
sshdforks a child process for every connection, the memory layout (and ASLR offset) remains consistent if the parent server doesn't restart. The attacker can brute-force the timing and memory layout over thousands of attempts (taking ~6-8 hours on average).
The Impact: Root Shell
If the exploit succeeds, the impact is total compromise.
-
Privilege Level: The vulnerable process runs as
rootbecause authentication hasn't happened yet (sshd needs root privileges to bind the port and eventually switch users). -
Scope: The attacker gains full control over the server. They can install persistent backdoors, steal data, or pivot to internal networks.
-
Constraints: This specifically targets glibc-based Linux systems. OpenBSD is not affected (different security mechanisms), and Windows/macOS implementations vary. However, considering the vast majority of cloud infrastructure runs on Linux/glibc, the target surface is massive.
The Fix: Remediation
If you manage Linux servers, you have two options: patch now, or apply the config workaround.
1. The Patch: Upgrade to OpenSSH 9.8p1. This version fixes the regression by removing the unsafe logging from the signal handler.
2. The Workaround (Immediate):
If you cannot patch immediately, you can mitigate the race condition by setting the LoginGraceTime to 0 in your sshd_config.
# /etc/ssh/sshd_config
LoginGraceTime 0[!WARNING] Setting
LoginGraceTime 0exposes you to a different risk: Denial of Service. Without a timeout, an attacker can exhaust all available connection slots by opening connections and never completing the handshake. However, a DoS is infinitely better than a root RCE. Pick your poison.
Official Patches
Fix Analysis (1)
Technical Appendix
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:HAffected Systems
Affected Versions Detail
| Product | Affected Versions | Fixed Version |
|---|---|---|
OpenSSH OpenBSD | >= 8.5p1, < 9.8p1 | 9.8p1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-364 |
| Attack Vector | Network |
| CVSS | 8.1 (High) |
| Impact | Remote Code Execution (Root) |
| Architecture | x86 (glibc), amd64 (glibc) |
| Complexity | High (Race Condition) |
MITRE ATT&CK Mapping
Vulnerability Timeline
Subscribe to updates
Get the latest CVE analysis reports delivered to your inbox.