Five OpenSMTPD upstream fixes from a corrected per-claim disclosure
Gilles Chehade, OpenSMTPD’s lead maintainer, committed five hardening patches to the OpenBSD tree on 2026-05-26 following a corrected per-claim disclosure to the security team. All five name the practice as the diff author. None is remote code execution; the original chained-to-RCE framing was retracted three days earlier. This is the resolution side of the case study at the centre of The Calculator Discipline.
What landed today
Five commits by Gilles Chehade (poolpOrg@), OpenSMTPD’s lead maintainer, landed in openbsd/src on 2026-05-26. All five name the practice as the diff author. The summary:
| Commit | Subject | File | Class |
|---|---|---|---|
| 388bcda | Reject oversized sockaddr payloads received over privsep IPC | mproc.c |
Defense-in-depth, PR:H |
| 3b4f66f | clear userinfo before sending over imsg | lka.c |
Same-uid stack residue (defense-in-depth) |
| c2e63d9 | Ensure pending asynchronous lookups do not retain dangling smtp_session references after teardown | smtp_session.c |
Real UAF — conditional remote DoS |
| b529354 | validate encrypted queue buffer sizes before processing auth tag and IV data | crypto.c |
Hardening (exploit framing retracted) |
| 2c717ae | Zero the temporary envelope parsing buffers before use | queue_backend.c |
Defense-in-depth zero-init |
Per-commit technical detail, including the verbatim public commit-body language for the two commits that carry it (388bcda and c2e63d9), is in the full disclosure.
Fix availability
The five commits are in OpenBSD −current as of 2026-05-26. Release timing and any backport to the supported −stable branches are the OpenBSD project’s call; the practice does not speculate on them.
The authoritative sources are:
- openbsd.org — current released version and release notes
- openbsd.org/faq/faq5.html — release / −current / −stable policy
- openbsd.org/errata79.html — OpenBSD 7.9 errata
- openbsd.org/errata78.html — OpenBSD 7.8 errata
- github.com/openbsd/src — tree mirror
The lka-side hostnametable configuration is the operational hook worth noting in the interim: a listener configured without hostnametable (or another lka-side table) does not reach the c2e63d9 use-after-free path. The OpenSMTPD-portable distribution at github.com/OpenSMTPD/OpenSMTPD is a separate downstream and follows its own release process.
Why this is published as a walk-back
The original disclosure to security@openbsd.org on 2026-05-23 framed six findings as “chained to Remote/Local Code Execution”. That framing was wrong. The disclosure had been produced from an AI-assisted source review the practice had not independently verified against the current OpenBSD 7.8 amd64 tree before sending, and the chain framing was inflation that the source observations did not actually support.
Theo de Raadt replied the same day with a single pointed question, paraphrased here with respect to the privacy of security@ correspondence: whether the practice was actually claiming to have exploited the chain; whether execution had been achieved.
The honest answer was no. No chain had been built, no execution had been achieved, no working proof-of-concept existed for any of the six claims. Each claim contained a real source observation, but the chain framing was assembled, not demonstrated.
The walk-back that followed is what produced the five fixes that landed today:
| Date | Event |
|---|---|
| 2026-05-23 | Original six-claim disclosure sent to security@openbsd.org, framed as “chained to RCE”. |
| 2026-05-23 | Theo de Raadt replies asking, in substance, whether execution had been achieved. |
| 2026-05-25 | Per-claim verification of all six claims against the current usr.sbin/smtpd/ tree at OpenBSD 7.8 amd64. Three real but inflated; one trivial same-uid residue; two retracted as fabricated. |
| 2026-05-26 07:00 | Corrected per-claim reply sent to Theo. Opening sentence: “No. I did not achieve execution.” |
| 2026-05-26 14:31 | Theo replies that he is forwarding the corrected list to the OpenSMTPD maintainers, who will commit what they judge worthwhile. |
| 2026-05-26 | Within hours, Gilles Chehade (poolpOrg@) commits the five fixes listed in the table above. All five credit the practice as the diff author. |
Two of the original six claims were retracted as fabricated. The smtp_reply vsnprintf %.*s trigger does not exist — no current format string in the function can produce a write greater than the 4096-byte buffer. The crypto_decrypt_buffer exploit framing fails the caller-bounds trace because the underflow lands in the safe return 0 decrypt-failure path before the dangerous memcpy is reached; upstream shipped the explicit input validation anyway as defense-in-depth (b529354), but the exploit story behind it does not hold.
A sixth real defect from the original mail — a double-close in queue_message_fd_r()’s error path in queue_backend.c — is not in this 2026-05-26 batch. Whether it lands separately is for the maintainers.
Severity, honestly
The five fixes that landed are, by category:
- One real source-level use-after-free (
c2e63d9) reachable only when the administrator has configuredhostnametableor another lka-side table on a listener. Crash-grade remote DoS. Not code execution. - One PR:H defense-in-depth IPC overflow guard (
388bcda) on a path that requires a peer mproc process already running as_smtpdto reach. - One same-uid stack-residue zero-init (
3b4f66f) on an IPC channel that is not a privsep boundary — an attacker who can receive the leak does not need a leak. - Two pure hardening patches (
b529354,2c717ae) on paths where the conservative input-validation and zero-init posture is desirable but where no exploitable trigger has been demonstrated.
None of these is remote code execution. None is a chain. None is pre-auth network impact on the shipped binary. Defense-in-depth, hardening, and conditional remote DoS are the honest words; the practice intends to use them consistently.
Methodology context
The methodological lesson behind the walk-back is documented in a separate paper: The Calculator Discipline: A Taxonomy and Pre-Send Filter for AI-Assisted Vulnerability Disclosure Hallucinations (DOI 10.5281/zenodo.20393083), published 2026-05-26. The paper presents this OpenSMTPD case as its second case study, with per-claim verification preserved at the time of publication.
The four-verifier pre-send filter described in the paper’s §6 is published as penfold.disclose.hallucination_check in the practice’s open-source penfold toolkit (BSD-2-Clause, github.com/jetnoir/penfold). The original 2026-05-23 mail would have triggered severity_inflation and caller_bounds_gate verdicts had the verifier existed at the time of drafting. It does now.
The wider point survives. AI-assisted source review is useful, but it is not ground truth. A pre-send filter that catches the mechanical failure modes — bug-shape fabrication, evidence fabrication, severity inflation, trivial-as-critical — needs to sit between the AI’s confident output and the maintainer’s inbox. The five fixes today are what happens when that filter is applied retroactively, by hand, and the result is forwarded honestly. Other researchers running AI-assisted source review at this volume would benefit from the same posture.
What this case study is not
- Not a victory lap. The five fixes that landed are the result of a correction, not a clean find. Publishing them as if they were the latter would be a worse outcome than retracting the original mail.
- Not a CVE request. Defense-in-depth and conditional-DoS findings without a demonstrated exploitable trigger do not meet the bar most CNAs apply. The upstream commits are the record of the work.
- Not the end of the methodology change. The practice’s pre-send filter now blocks drafts that would trigger any of the four mechanical verdicts. The two judgement-shaped failure modes — severity inflation and trivial-as-critical — remain a researcher-judgement problem; the filter offers only structural hooks for them.