From 1d38781da934809e6ce0b8c3718c4b3bccdfe1d2 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Wed, 28 Dec 2022 19:39:06 +0000 Subject: [PATCH] Fix recursion on dns_again_means_nonexist. Bug 2911 --- doc/doc-txt/ChangeLog | 8 +++++ src/src/dns.c | 12 ++++++++ test/confs/2202 | 18 +++++++++-- test/scripts/2200-dnsdb/2202 | 8 +++++ test/stderr/2202 | 58 +++++++++++++++++++++++++++++++++++- test/stdout/2202 | 8 +++++ 6 files changed, 108 insertions(+), 4 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 95c15b96b..ee86f52d6 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -86,6 +86,14 @@ JH/18 Fix a fencepost error in logging. Previously (since 4.92) when a log line misleading message "bad memory reference; pool not found". Found and traced by Jasen Betts. +JH/19 Bug 2911: Fix a recursion in DNS lookups. Previously, if the main option + dns_again_means_nonexist included an element causing a DNS lookup which + iteslf returned DNS_AGAIN, unbounded recursion occurred. Possible results + included (though probably not limited to) a process crash from stack + memory limit, or from excessive open files. Replace this with a paniclog + whine (as this is likely a configuration error), and returning + DNS_NOMATCH. + Exim version 4.96 ----------------- diff --git a/src/src/dns.c b/src/src/dns.c index 4e01d8661..2355409ec 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -802,6 +802,7 @@ dns_basic_lookup(dns_answer * dnsa, const uschar * name, int type) int rc; #ifndef STAND_ALONE const uschar * save_domain; +static BOOL try_again_recursion = FALSE; #endif /* DNS lookup failures of any kind are cached in a tree. This is mainly so that @@ -906,11 +907,22 @@ if (dnsa->answerlen < 0) switch (h_errno) /* Cut this out for various test programs */ #ifndef STAND_ALONE + if (try_again_recursion) + { + log_write(0, LOG_MAIN|LOG_PANIC, + "dns_again_means_nonexist recursion seen for %s (assuming nonexist)", + name); + return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), DNS_NOMATCH); + } + + try_again_recursion = TRUE; save_domain = deliver_domain; deliver_domain = string_copy(name); /* set $domain */ rc = match_isinlist(name, CUSS &dns_again_means_nonexist, 0, &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL); deliver_domain = save_domain; + try_again_recursion = FALSE; + if (rc != OK) { DEBUG(D_dns) debug_printf("returning DNS_AGAIN\n"); diff --git a/test/confs/2202 b/test/confs/2202 index 825be913e..64c638d9a 100644 --- a/test/confs/2202 +++ b/test/confs/2202 @@ -1,21 +1,33 @@ # Exim test configuration 2202 -CONNECTCOND= - .include DIR/aux-var/std_conf_prefix primary_hostname = myhost.test.ex # ----- Main settings ----- +acl_smtp_vrfy = vrfy acl_smtp_rcpt = rcpt -dns_again_means_nonexist = * disable_ipv6 +.ifdef DNS_RECURSE +hosts_treat_as_local = test.again.dns +domainlist try_again_dns_list = @mx_any +dns_again_means_nonexist = !+try_again_dns_list +# that last line tries to set up a recursion +.else +dns_again_means_nonexist = * +.endif + # ----- ACL ----- begin acl +vrfy: +.ifdef DNS_RECURSE + warn domains = +try_again_dns_list +.endif + rcpt: accept hosts = +ignore_unknown : \ *.$sender_address_domain : \ diff --git a/test/scripts/2200-dnsdb/2202 b/test/scripts/2200-dnsdb/2202 index e87087b6b..eb24fbffa 100644 --- a/test/scripts/2200-dnsdb/2202 +++ b/test/scripts/2200-dnsdb/2202 @@ -1,8 +1,16 @@ # dns_again_means_nonexist munge dnssec +# +# +# exim -d -bh HOSTIPV4 helo test mail from: rcpt to: quit **** +# +# This used to recurse via dns_again_means_nonexist +exim -d -DDNS_RECURSE -bh HOSTIPV4 +vrfy a@test.again.dns +**** diff --git a/test/stderr/2202 b/test/stderr/2202 index f2856b019..85cbb9e45 100644 --- a/test/stderr/2202 +++ b/test/stderr/2202 @@ -34,7 +34,7 @@ log directory space = nnnnnK inodes = nnnnn check_space = 10240K inodes = 100 SMTP>> 250 OK SMTP<< rcpt to: using ACL "rcpt" -processing "accept" (TESTSUITE/test-config 23) +processing "accept" (TESTSUITE/test-config 35) check hosts = +ignore_unknown : *.$sender_address_domain : $sender_address_domain : ${lookup dnsdb{>:defer_never,mxh=$sender_address_domain}} search_open: dnsdb "NULL" search_find: file="NULL" @@ -93,3 +93,59 @@ LOG: smtp_connection MAIN SMTP connection from the.local.host.name (test) [ip4.ip4.ip4.ip4] closed by QUIT search_tidyup called >>>>>>>>>>>>>>>> Exim pid=p1234 (fresh-exec) terminating with rc=0 >>>>>>>>>>>>>>>> +Exim version x.yz .... +changed uid/gid: forcing real = effective + uid=uuuu gid=CALLER_GID pid=p1235 +configuration file is TESTSUITE/test-config +admin user +changed uid/gid: privilege not needed + uid=EXIM_UID gid=EXIM_GID pid=p1235 +originator: uid=CALLER_UID gid=CALLER_GID login=CALLER name=CALLER_NAME +sender address = CALLER@myhost.test.ex +sender_fullhost = [ip4.ip4.ip4.ip4] +sender_rcvhost = [ip4.ip4.ip4.ip4] +host in hosts_connection_nolog? no (option unset) +LOG: smtp_connection MAIN + SMTP connection from [ip4.ip4.ip4.ip4] +host in host_lookup? no (option unset) +set_process_info: pppp handling incoming connection from [ip4.ip4.ip4.ip4] +host in host_reject_connection? no (option unset) +host in sender_unqualified_hosts? no (option unset) +host in recipient_unqualified_hosts? no (option unset) +host in helo_verify_hosts? no (option unset) +host in helo_try_verify_hosts? no (option unset) +host in helo_accept_junk_hosts? no (option unset) +SMTP>> 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +smtp_setup_msg entered +SMTP<< vrfy a@test.again.dns +host in smtp_accept_max_nonmail_hosts? yes (matched "*") +using ACL "vrfy" +processing "warn" (TESTSUITE/test-config 28) +check domains = +try_again_dns_list +DNS lookup of test.again.dns (MX) using fakens +DNS lookup of test.again.dns (MX) gave TRY_AGAIN +DNS lookup of test.again.dns (MX) using fakens +DNS lookup of test.again.dns (MX) gave TRY_AGAIN +LOG: MAIN PANIC + dns_again_means_nonexist recursion seen for test.again.dns (assuming nonexist) +DNS: couldn't fake dnsa len +DNS: no SOA record found for neg-TTL + writing neg-cache entry for test.again.dns-MX-xxxx, ttl -1 +test.again.dns in "@mx_any"? no (end of list) +test.again.dns in dns_again_means_nonexist? yes (end of list) +test.again.dns is in dns_again_means_nonexist: returning DNS_NOMATCH +DNS: couldn't fake dnsa len +DNS: no SOA record found for neg-TTL + update neg-cache entry for test.again.dns-MX-xxxx, ttl -1 +test.again.dns in "@mx_any"? no (end of list) +test.again.dns in "+try_again_dns_list"? no (end of list) +warn: condition test failed in ACL "vrfy" +end of ACL "vrfy": implicit DENY +SMTP>> 252 Administrative prohibition +LOG: MAIN REJECT + H=[ip4.ip4.ip4.ip4] rejected VRFY a@test.again.dns +SMTP>> 421 myhost.test.ex lost input connection +LOG: smtp_connection MAIN + SMTP connection from [ip4.ip4.ip4.ip4] lost D=qqs +search_tidyup called +>>>>>>>>>>>>>>>> Exim pid=p1235 (fresh-exec) terminating with rc=0 >>>>>>>>>>>>>>>> diff --git a/test/stdout/2202 b/test/stdout/2202 index f2bf2f07c..6fcd39719 100644 --- a/test/stdout/2202 +++ b/test/stdout/2202 @@ -8,3 +8,11 @@ 250 OK 550 Administrative prohibition 221 myhost.test.ex closing connection + +**** SMTP testing session as if from host ip4.ip4.ip4.ip4 +**** but without any ident (RFC 1413) callback. +**** This is not for real! + +220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +252 Administrative prohibition +421 myhost.test.ex lost input connection -- 2.30.2