CVE-2026-45185
.Intro
Dear reader,
What follows is, before anything else, a story. One of those old, well-worn ones. 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. Told, this time, in a setting where stories of that shape are not usually told.
These pages are the by-product of the early days of testing a product we are building. A product focused on finding and detecting vulnerabilities in native code. So what you are about to read is two things at once. It is the technical account of a vulnerability of worldwide reach that we found and reported and also it is, more quietly, the account of how I tried to make peace with the new shape of the world we are now living in.
I have spent almost ten years writing exploits professionally, and twenty in security altogether. In recent years large language models have arrived to shift the paradigm, and until now I had kept myself on the sidelines whenever it came to using them for writing exploits. This is the first time I have set that watch down and let one of these models into the place where, until now, only my own hands had ever been. Furthermore, in my entire career I had never once read a line of Exim's source. I remembered, vaguely, a Qualys write-up (https://www.qualys.com/2021/05/04/21nails/21nails.txt) from years ago that had blown my mind at that time, but I had never sat down with the code itself.
I hope what follows finds two kinds of readers: the ones who came for the technical depth, and the ones who came for the story. I would be glad if it found both at once.
The vulnerability
The bug is a use-after-free triggered when a TLS connection is handled by GnuTLS (the default TLS library on many Debian-based distributions, including Ubuntu). During TLS shutdown, Exim frees its TLS transfer buffer — but a nested BDAT receive wrapper can still process incoming bytes and end up calling ungetc(), which writes a single character (
) into the freed region. That one-byte write lands on Exim's allocator metadata, corrupting the allocator's internal shape; the exploit then leverages that corruption to gain further primitives.
... continue reading