Overview
A use-after-free in Exim's SMTP receive path, reachable by an unauthenticated client on any server where GnuTLS is the TLS library — the default on Debian-based distributions including Ubuntu. Exploitation requires almost no special configuration on the server, which is what makes it one of the highest-caliber bugs found in Exim to date.
The write primitive looks weak: a single newline character placed into a freed region. That one byte lands on the allocator's metadata, and the published exploit chain escalates it from there to remote code execution.
Triggering this bug requires almost no special configuration on the server. That, more than the technical shape of the corruption itself, is what makes it one of the highest-caliber bugs discovered in Exim to date.
Affected products
- Exim 4.97 as shipped in Debian-based default installations, including Ubuntu 24.04 LTS
- Any Exim build where GnuTLS is the active TLS library
- Servers accepting STARTTLS and BDAT (RFC 3030 chunking) from unauthenticated clients
Disclosure timeline
- 01 May 2026
- Vulnerability submitted to security@exim.org
- 05 May 2026
- Maintainers acknowledged the vulnerability and confirmed a fix in their private repository
- 08 May 2026
- Exim maintainers notified the distributions
- 10 May 2026
- Restricted access provided to distributions
- 10 May 2026
- CVE-2026-45185 assigned
- 12 May 2026
- Public release and coordinated distribution release
Technical details
How the free happens
After a successful STARTTLS handshake, Exim allocates a 4096-byte plaintext transfer buffer and swaps its SMTP receive function pointers for TLS-aware wrappers. When the TLS connection shuts down, that buffer is freed.
BDAT chunking complicates the shutdown. A BDAT chunk pushes the current receive functions down into a second row of pointers and installs its own wrappers on top; the lower row still points at the TLS callbacks. The body parser does not return to its caller until the chunk is fully consumed, so the buffer can be freed mid-loop while the loop is still running.
How the use happens
A missing CRLF repair later in the same loop calls back through the saved lower-layer pointer into the TLS ungetc handler, which writes one character — a newline — at the buffer's low-water mark. The buffer is already gone, so the write lands in freed memory and corrupts the allocator's bookkeeping.
From there the published chain pivots on that corruption, first against glibc's allocator and then, once ASLR is in play, against Exim's own pool allocator.
Dead.Letter (CVE-2026-45185): How XBOW Found an Unauthenticated RCE on Exim