Exim CVE-2026-45185: Unauthenticated RCE via GnuTLS Use-After-Free (Dead.Letter)
Published: 2026-05-13 • Category: Security / Email / CVE
Overview
On May 11, 2026, XBOW publicly disclosed CVE-2026-45185, a critical vulnerability in Exim, the most widely deployed Mail Transfer Agent on the Internet. The vulnerability, codenamed "Dead.Letter", is an unauthenticated remote code execution (RCE) vulnerability triggered through a use-after-free in Exim's GnuTLS TLS handling layer. What makes this bug particularly severe is that it requires almost no special configuration on the server to be exploitable, and it affects the default GnuTLS-based installation used by Debian, Ubuntu, and many other distributions.
This marks the first time the XBOW researcher, a 20-year security veteran who spent nearly a decade writing exploits professionally, used AI/LLM tooling to discover and help develop a full exploit chain — a decision he describes as "setting that watch down for the first time."
The Vulnerability: A One-Byte Write to Freedom
At its core, CVE-2026-45185 is a use-after-free vulnerability that occurs when Exim's TLS shutdown procedure frees the transfer buffer while a nested BDAT (RFC 3030 CHUNKING) receive wrapper is still processing incoming bytes. The sequence:
- TLS shutdown causes the free: Exim frees its TLS transfer buffer (
xfer_buffer) viatls_close() - BDAT wrapper is still active: The BDAT receive functions had saved the TLS callbacks in a "lower row" that isn't touched by
tls_close() - The use writes to freed memory: The read loop calls
bdat_ungetc('\n'), which goes throughtls_ungetc()and writes a single newline character into the freed buffer - Allocator corruption: That one-byte write lands on Exim's custom allocator metadata, corrupting the allocator's internal structures
- Primitives escalate to RCE: The exploit leverages the allocator corruption to gain further read/write primitives, eventually achieving full remote code execution
Technical Deep Dive
Exim's TLS Architecture
When a client issues a STARTTLS command over a plaintext SMTP session, Exim's command dispatcher calls tls_server_start(). This function:
- Initializes a GnuTLS server session
- Allocates a 4096-byte transfer buffer (
xfer_buffer) viastore_malloc() - Replaces the SMTP receive function pointers (
receive_getc,receive_ungetc, etc.) with TLS-aware wrappers - Runs the TLS handshake
The transfer buffer is a plaintext area where tls_getc() reads decrypted bytes one at a time, refilling from gnutls_record_recv() when empty.
The BDAT Layer
BDAT (RFC 3030 CHUNKING) is a modal SMTP extension where the client declares the body size upfront. Exim handles this by maintaining a second row of function pointers (lwr_receive_*). When a BDAT chunk begins, bdat_push_receive_functions() saves the current row (which could be TLS wrappers) down to lwr_receive_* and overwrites the top row with BDAT wrappers. The BDAT wrappers delegate actual I/O to the saved lower layer.
Key insight: The lower row (lwr_receive_*) is only supposed to be touched by bdat_push/pop_receive_functions(). No other code path touches it.
The Free
Inside read_message_bdat_smtp(), the loop reads body bytes via bdat_getc(), which calls lwr_receive_getc() (which is tls_getc()). tls_getc() calls tls_refill(), which calls gnutls_record_recv(). When gnutls_record_recv() returns 0 (TLS EOF):
tls_close(NULL, TLS_NO_SHUTDOWN); // frees state->xfer_buffer
return FALSE;
Inside tls_close(), the top-level receive_* callbacks are restored to plain smtp_* functions, but the lwr_receive_* row is NOT touched. The xfer_buffer pointer is freed but never set to NULL.
The Use
When bdat_getc() returns EOF (EOD), the loop enters the EOD case. If a \r was seen without a following \n, the missing-CRLF repair fires:
bdat_ungetc('\n');
This calls the saved lwr_receive_ungetc(), which is still tls_ungetc(). And tls_ungetc() writes through the freed pointer:
ssl_xfer_buffer[--ssl_xfer_buffer_lwm] = ch;
A single \n byte is written into freed memory, landing on allocator metadata.
From One Byte to RCE
The exploit chain involves multiple stages:
- Allocator corruption: The single byte write corrupts Exim's store allocator pool metadata
- Heap grooming: DKIM verification in the cleartext fallback path runs
pdkim_feed(), which performs controlledstore_malloc()allocations that can reclaim the freed chunk - Chunk reuse: The XBOW researcher shows how to control the size and contents of the allocation that takes over the freed buffer, populating it with attacker-controlled data that persists through the use-after-free
- Controlled corruption: Once the allocator's internal structures are corrupted with predictable values, the attacker gains read/write primitives
- Full RCE: These primitives are escalated to execute arbitrary code on the mail server
Why This Matters: The AI Discovery Angle
XBOW's write-up is remarkable not just for the technical depth, but for what it represents. The researcher describes spending almost ten years writing exploits professionally, and twenty years in security. This is the first time he used AI/LLM tools in the exploit development process.
As he put it: "I had never once read a line of Exim's source" before starting this research. The Qualys 21Nails write-up from 2021 was mentioned as having "blown his mind" at the time, but he'd never sat down with Exim's code himself.
The vulnerability was found during early testing of XBOW's own product — an AI-powered native code vulnerability detection tool. This represents a paradigm shift: AI tools that understand the full semantics of C code can now find subtle, multi-step, use-after-free vulnerabilities in mature, well-audited codebases like Exim.
Impact and Scope
Exim is the Internet's most deployed Mail Transfer Agent, handling a significant portion of global email traffic. The vulnerability affects:
- Default installations of Exim on Debian-based distributions (including Ubuntu 24.04 LTS) that use GnuTLS
- All Exim 4.97 installations with GnuTLS enabled (the default on many systems)
- Systems using both STARTTLS and BDAT CHUNKING (both are standard SMTP features, almost universally available)
The fact that no special server configuration is required makes this one of the highest-caliber bugs discovered in Exim. An unauthenticated attacker on the network can send a crafted SMTP session that triggers the vulnerability without needing any credentials or prior access.
Patch and Mitigation
Exim maintainers have released patches addressing CVE-2026-45185. As of the disclosure date:
- Check your distribution's package manager for updated Exim packages
- Monitor the Exim website and mailing lists for patch announcements
- A temporary workaround is to disable CHUNKING/BDAT support if you cannot patch immediately
- If using GnuTLS, ensure you have the latest version (though the bug is in Exim's integration, not GnuTLS itself)
- Consider restricting SMTP access to trusted networks as a defense-in-depth measure
XBOW's "Dead.Letter" — More Than a Technical Report
The XBOW write-up is deliberately written as both a technical document and a personal narrative. The title "Dead.Letter" plays on both the email context (dead letters, undeliverable mail) and the cultural reference. The researcher frames the discovery as a story of "encounters and misencounters, of broken hearts and quiet betrayals, of loves once thought to be forever turning out to be something else entirely" — a meditation on the relationship between human security researchers and the AI tools that are transforming their craft.
He hoped the report would find "two kinds of readers: the ones who came for the technical depth, and the ones who came for the story."
Conclusion
CVE-2026-45185 is a landmark vulnerability in Internet email infrastructure. A critical, unauthenticated RCE in Exim — discovered by a veteran exploit developer who had never touched the code before, using AI tooling for the first time. It joins the growing list of evidence that AI-powered vulnerability research is not a future trend but a present reality, and that open source infrastructure projects need to adapt to this new threat landscape.