java-topology/whitepaper/outreach/postfix.md

2.8 KiB
Raw Blame History

Postfix — CWE-407 Disclosure Brief

2026-03-27 · Patch available — awaiting upstream merge

Finding

Two O(n²) defects in Postfix's SMTP routing and address masquerading. One scans a domain list on every RCPT-TO; the other scans exception and masquerade domain lists per address. Measured at 500× and 200× respectively. Patches ready for upstream review.

The Defects

postfix-0001 (PATCHED — HIGH): resolve.c:161

/* Inside resolve_addr() — per RCPT-TO per message: */
/* string_list_match() — O(K) ARGV linear scan */
if (string_list_match(virtual_transport_maps, domain)) { ... }
if (string_list_match(relay_transport_maps, domain)) { ... }
/* O(K) per domain lookup — called for every recipient address */

string_list_match() performs O(K) linear ARGV scan for virtual/relay domain lookups on every RCPT-TO command. Measured ratio: 500×.

postfix-0002 (PATCHED — HIGH): cleanup_masquerade.c:108

/* Per address in masquerade rewriting: */
/* O(E) exceptions scan + O(D) masq-domains scan per address */
while ((cp = argv_iter(exceptions_iter)) != 0) {
    if (strcmp(cp, domain) == 0) ...  /* O(E) scan */
}

Linear scans over exception and masquerade domain lists per address rewrite. Measured ratio: 200×.

Complexity Proof

postfix-0001: For K=500 virtual/relay domain entries:

  • Per RCPT-TO: O(K) scan
  • Fixed: pre-built HTABLE hash → O(1) lookup
  • 500× measured ratio.

postfix-0002: For E=200 exception entries:

  • Per address: O(E) scan
  • Fixed: hash cache → O(1) with cache hit
  • 200× measured ratio.

Impact

All Postfix MTA deployments with virtual domain routing (nearly universal) and address masquerading. postfix-0001 fires on every incoming RCPT-TO for multi-domain setups. postfix-0002 fires on every outgoing message rewrite. Postfix is one of the most widely deployed MTAs on the internet, powering email for millions of domains. High-volume mail servers hit these defects on every message.

The Fix

postfix-0001: Replace string_list_match() ARGV scan with HTABLE hash:

/* Before */
if (string_list_match(transport_maps, domain)) { ... }  /* O(K) ARGV scan */

/* After */
/* CWE-407 fix: HTABLE for O(1) domain lookup instead of O(K) ARGV scan. */
if (htable_find(transport_htable, domain) != 0) { ... }

postfix-0002: Cache masquerade domain lookups in an HTABLE.

Patch

defects/postfix/patch/postfix-0001-0002-domain-htable.patch

What We Ask

  1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
  2. Validate the patch against your routing and masquerade test suites.
  3. Assess CVE eligibility — postfix-0001 fires on every RCPT-TO on multi-domain servers.
  4. Coordinate a disclosure date — we are targeting 90 days from first contact.

Contact: see cover email. This brief is confidential until coordinated disclosure.