Bugfix 1 (defect introduced: Postfix 3.1, date 20150607): null pointer read and heap data overread in the Postfix SMTP client's smtp_dns_reply_filter. Problem reported by TristanInSec, found with ASAN. Also reported by other people. Reproduction and real-world impact researched by Wietse. See below for root cause, reproduction, and impact. Bugfix 2: (defect introduced: Postfix 3.6, date: 20200710): panic (assertion failure and voluntary crash) while parsing a TLSA reply with length 3. Found during code maintenance. See below for root cause, reproduction, and impact. Root cause for bug 1: ===================== A missing 'break' statement after the code that converts a TLSA record to string. Reproduction for bug 1: ======================= The problem happens when smtp_dns_reply_filter is configured (this is disabled by default); the Postfix SMTP client is configured to use opportunistic or mandatory DANE authentication (this is disabled by default); the destination domain publishes a TLSA record that is empty or shorter than 20 bytes; and the OS is configured to use a resolver that passes such a TLSA record. For example, a zero-length TLSA record is blocked by BIND, Google DNS, OpenDNS, and by configurations that use systemd-resolved (the default on many LINUX systems); it is passed by Cloudflare, Quad9 DNS, and unbound, as long as these resolvers are used without systemd-resolved. Impact statement for bug 1: =========================== SMTP client termination with a null pointer read crash when the TLSA record length is zero; or an SMTP client data overread (or rarely, SMTP client termination with a read segfault crash) when 0 < record length < 20 bytes. The overread content is not disclosed. Performance impact of bug 1 and 2: ================================== The impact of SMTP client crashes (voluntary or not) is easily overstated. That said, crashes must be eliminated regardless of their impact. On systems that deliver fewer than one message per minute, an SMTP client crash can result in a delay of up to one minute for email delivery to other destination domains. On systems with a larger traffic volume, the impact of an SMTP client crash on deliveries to other destination domains is minor because Postfix reuses SMTP client processes and replaces a failed process within seconds (self-healing); the practical impact is believed to be no worse than that of an uncooperative receiver that tarpits SMTP connections from Postfix to one or more destination domains under their control (by replying within Postfix SMTP client read time limits which are several minutes by default). Root cause for bug 2: ===================== An incorrect test 'length < 3' instead of 'length <= 3' causes a safety check to fail when a TLSA parser attempts to create zero-length storage for a non-existent TLSA certificate association data field. Reproduction for bug 2: ======================= The problem happens when the Postfix SMTP client is configured to use opportunistic or mandatory DANE authentication (this is disabled by default); a destination domain publishes a TLSA record with a length of three bytes; and the OS is configured to use a resolver that passes such a TLSA record. For example, a length-three TLSA record is blocked by BIND, and by configurations that use systemd-resolved (the default on many LINUX systems). It is passed by many other resolvers. Bug 2 enables an attack that is more potent than bug 1. - An attack with a length-three TLSA reply does not depend on smtp_dns_reply_filter configuration. - An attack with a length-three TLSA reply propagates through more resolvers than an attack with a length-zero TLSA reply. Impact statement for bug 2: =========================== SMTP client voluntary termination (crash) after an assertion failure. This is a fail-safe mechanism. See also above for "Performance impact of bug 1 and 2". diff '--exclude=man' '--exclude=html' '--exclude=README_FILES' '--exclude=INSTALL' --no-dereference -r -ur --new-file /var/tmp/postfix-3.12-20260516/src/dns/dns_strrecord.c ./src/dns/dns_strrecord.c --- /var/tmp/postfix-3.12-20260516/src/dns/dns_strrecord.c 2023-02-13 15:58:00.000000000 -0500 +++ ./src/dns/dns_strrecord.c 2026-05-20 17:20:10.150886351 -0400 @@ -99,6 +99,8 @@ } else { vstring_sprintf_append(buf, "[truncated record]"); } + /* 202605 Missing break found by TristanInSec using ASAN. */ + break; /* * We use the SOA record TTL to determine the negative reply TTL. We diff '--exclude=man' '--exclude=html' '--exclude=README_FILES' '--exclude=INSTALL' --no-dereference -r -ur /var/tmp/postfix-3.12-20260516/src/tls/tls_dane.c ./src/tls/tls_dane.c --- /var/tmp/postfix-3.12-20260516/src/tls/tls_dane.c 2026-05-10 10:57:44.000000000 -0400 +++ ./src/tls/tls_dane.c 2026-05-31 16:18:14.244072572 -0400 @@ -518,7 +518,7 @@ q, a, r, rr->type); /* Drop truncated records */ - if ((dlen = rr->data_len - 3) < 0) { + if ((dlen = rr->data_len - 3) <= 0) { msg_warn("%s%s%s: truncated TLSA RR length == %u", q, a, r, (unsigned) rr->data_len); return (0);