java-topology/defects/postfix/patch/postfix-0002.patch

63 lines
2.3 KiB
Diff

# UNDF: UNDF-2026-000000217
--- a/postfix/src/cleanup/cleanup_masquerade.c
+++ b/postfix/src/cleanup/cleanup_masquerade.c
@@ -52,6 +52,7 @@
#include <mail_params.h>
#include <tok822.h>
#include <quote_822_local.h>
+#include <htable.h>
/* Application-specific. */
@@ -75,6 +76,8 @@ int cleanup_masquerade_external(CLEANUP_STATE *state, VSTRING *addr,
ARGV *masq_domains)
{
char *domain;
+ /* Lazy-built hash cache for masq_domains exact matches (key=domain, value=masq) */
+ static HTABLE *masq_domain_cache = 0;
ssize_t domain_len;
char **masqp;
char *masq;
@@ -96,11 +99,26 @@ int cleanup_masquerade_external(CLEANUP_STATE *state, VSTRING *addr,
if (excluded)
return (0);
}
+
+ /*
+ * CWE-407 fix: Build a hash cache of exact-match masquerade domains on
+ * first use so we avoid O(D) scan for every address processed.
+ * Wildcard/prefix masquerade domains (those starting with '!') still
+ * require the linear scan — handle them in a second pass.
+ */
+ if (masq_domain_cache == 0) {
+ masq_domain_cache = htable_create(masq_domains->argc * 2 + 1);
+ for (char **p = masq_domains->argv; *p != 0; p++) {
+ char *m = *p;
+ int neg = 0;
+ while (*m == '!') { neg = !neg; m++; }
+ if (*m && strchr(m, '.') != 0 && !neg)
+ htable_enter(masq_domain_cache, m, m);
+ }
+ }
+
/*
- * If any parent domain matches the list of masquerade domains, replace
- * the domain in the address and terminate. If the domain matches a
- * masquerade domain, leave it alone. Order of specification matters.
+ * Fast path: O(1) hash lookup for exact-match masquerade domains.
+ * Fall through to linear scan only for prefix/negated patterns.
*/
+ {
+ char *cached = htable_find(masq_domain_cache, domain);
+ if (cached) {
+ if (msg_verbose)
+ msg_info("masquerade (cached): %s -> %s", domain, cached);
+ vstring_truncate(addr, name_len + 1);
+ vstring_strcat(addr, cached);
+ return (1);
+ }
+ }
+
for (masqp = masq_domains->argv; (masq = *masqp) != 0; masqp++) {
for (truncate = 1; *masq == '!'; masq++)
truncate = !truncate;