Exim CVE-2026-45185: "Dead.Letter" GnuTLS Use-After-Free, Upgrade Immediately
A Mail Server Vulnerability With No Workaround
The Exim mail server project announced a critical use-after-free vulnerability in its GnuTLS backend. All versions from 4.97 through 4.99.2 are affected. The only fix is upgrading to 4.99.3.
What makes this vulnerability particularly dangerous: triggering the bug requires almost no special configuration on the server. An attacker needs only a TLS connection and access to the CHUNKING (BDAT) SMTP extension—both standard on modern mail servers. The exploit path is straightforward enough that this is one of the highest-caliber bugs discovered in Exim to date.
No mitigation exists except upgrading. No workaround. No configuration change. Just patch or remain vulnerable.
CVE-2026-45185: The Vulnerability
Severity: Critical
Affected Versions: Exim 4.97 through 4.99.2 (GnuTLS builds only)
Not Affected: OpenSSL builds, Exim 4.99.3 and later
Attack Vector: Remote, requires TLS connection + BDAT SMTP extension
Impact: Heap corruption, potential remote code execution
What It Is: Use-After-Free in BDAT Handling
A use-after-free vulnerability occurs when a program continues to access memory that's already been freed. In this case, the vulnerability is triggered during BDAT (binary data transfer) message body handling.
Here's the attack scenario:
- Attacker establishes TLS connection to the Exim server
- Attacker sends TLS close_notify alert while BDAT message body transfer is still in progress (before body is complete)
- Attacker sends final byte in cleartext on the same TCP connection after the TLS session
- Exim attempts to write to a freed memory buffer during TLS teardown, causing heap corruption
The vulnerability exists because Exim doesn't properly reset its input processing stack when receiving a TLS close notification during active BDAT transfer. Stale pointers remain, and subsequent writes corrupt the heap.
Technical Depth
BDAT (Binary Data Transfer) is an SMTP extension that allows chunked message body transmission. The extension is useful for large messages but requires proper state management during BDAT transfers.
The attack exploits a race condition in the TLS/BDAT interaction:
- Normal flow: BDAT transfer completes → TLS session closes cleanly
- Exploit flow: TLS close_notify arrives → BDAT still active → input stack not reset → stale pointers remain → next write corrupts heap
Who's Affected?
Exim versions: 4.97, 4.98, 4.99.0, 4.99.1, 4.99.2
Configuration requirement: Exim must be compiled with GNUTLS=yes
Check your Exim build:
exim -v | grep -i gnutls
# Output shows SUPPORT_TLS with GnuTLS or OpenSSL
If the output shows OpenSSL instead of GnuTLS, you're not vulnerable to this specific flaw.
Who needs to patch:
- Mail server administrators running vulnerable Exim versions
- Any organization with BDAT (CHUNKING) extension enabled
- Any environment where GNUTLS TLS backend is used
Impact scope: Email infrastructure. Mail servers are high-value targets. Heap corruption in a mail server can lead to remote code execution, allowing attackers to:
- Read/modify email in transit
- Inject malicious content
- Access credential data
- Pivot to internal systems
The Attack: Low Barrier to Entry
What makes this vulnerability particularly dangerous is the attack simplicity. The exploit requires:
- Network access: Any external attacker can establish a TLS connection to an SMTP server
- No authentication: No need for valid credentials; TLS connection is enough
- Standard protocol: Only BDAT (CHUNKING) extension, which is standard on modern mail servers
- No special payload: The attack is a specific sequence of TLS and SMTP messages
An attacker doesn't need sophisticated malware or deeply embedded system knowledge. The attack is protocol-level exploitation: send specific messages in specific order, trigger heap corruption.
Proof of Concept (Conceptual)
import socket
import ssl
# Connect to Exim SMTP server
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('mail.target.com', 25))
# Receive SMTP greeting
response = sock.recv(1024)
print(response)
# Upgrade to TLS
sock.send(b'EHLO attacker.com\r\n')
response = sock.recv(1024)
print(response)
sock.send(b'STARTTLS\r\n')
response = sock.recv(1024)
print(response)
# Wrap socket with TLS
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
secure_sock = context.wrap_socket(sock, server_hostname='mail.target.com')
# Start BDAT transfer
secure_sock.send(b'BDAT 1000\r\n')
# Send partial body data (not 1000 bytes)
secure_sock.send(b'Partial')
# Send TLS close_notify without completing BDAT
secure_sock.unwrap()
# Send final byte in cleartext
sock.send(b'X')
# Heap corruption triggered
This is conceptual; actual exploitation depends on Exim's specific buffer layout and memory state.
Patching: The Only Fix
No workaround exists. Upgrade to Exim 4.99.3 or later immediately.
Check Current Version
exim -v
# Output shows version number
Upgrade to 4.99.3
From source:
# Download
cd /tmp
wget https://ftp.exim.org/pub/exim/exim4/exim-4.99.3.tar.xz
tar xJf exim-4.99.3.tar.xz
cd exim-4.99.3
# Build (note: include GnuTLS if needed)
./build/build
./build/install
# Verify
exim -v | grep "4.99.3"
From distribution repositories:
# Debian/Ubuntu
apt update && apt upgrade exim4
# RHEL/CentOS/Fedora
dnf update exim
# Alpine
apk update && apk upgrade exim
Restart Exim
sudo systemctl restart exim4
# or
sudo systemctl restart exim
# or
sudo /etc/init.d/exim4 restart
⚠️ Restart mail service carefully in production. Queue any pending messages first and verify mail routing during the restart.
Detection Before Patching
Until you can patch (if upgrade is delayed):
Monitor for exploitation attempts:
- Unusual process crashes involving Exim
- Segmentation faults in Exim logs
- Unexpected memory errors
Check logs for BDAT activity:
grep -i "bdat\|chunking" /var/log/exim/main.log
Monitor TCP connections:
# Watch for TLS connections followed by abrupt disconnects
ss -tnop | grep ESTAB
Alert on heap corruption:
journalctl -u exim | grep -i "segmentation\|corruption\|heap"
Real detection is difficult because the attack manifests as a memory error, not a protocol violation. The best detection is patching before the attack occurs.
Why GnuTLS Specifically?
The vulnerability exists only in Exim builds using GnuTLS as the TLS backend. Exim supports multiple TLS libraries:
- GnuTLS: Vulnerable (this flaw)
- OpenSSL: Not vulnerable
- Other TLS libraries: Not affected
The vulnerability is in how Exim's BDAT implementation interacts with GnuTLS session teardown. Different TLS libraries handle close_notify differently, resulting in different code paths.
If your Exim build uses OpenSSL, you're not affected by this specific vulnerability (though you should still keep updated for other potential issues).
Discovery and Remediation
The vulnerability was discovered by Federico Kirschbaum, an Exim contributor and maintainer who's also head of XBOW Security Lab. Kirschbaum's analysis emphasized the severity: the exploit requires minimal configuration and technical sophistication.
Exim's response was swift. Patched version 4.99.3 was released immediately with the fix: the input processing stack is cleanly reset when a TLS close notification is received during an active BDAT transfer, preventing the stale pointers from being used.
Upgrade Checklist
- [ ] Verify current Exim version (
exim -v) - [ ] Verify TLS backend (
exim -v | grep -i gnutls) - [ ] If running GnuTLS and version < 4.99.3: schedule upgrade immediately
- [ ] Test upgrade in staging environment first
- [ ] Plan upgrade window and notify users
- [ ] Back up current Exim configuration
- [ ] Download and verify Exim 4.99.3 from official source
- [ ] Compile/install from source or update via package manager
- [ ] Restart Exim and verify mail flow
- [ ] Monitor logs for errors
- [ ] Update patch management records