Fix recursion on dns_again_means_nonexist. Bug 2911
authorJeremy Harris <jgh146exb@wizmail.org>
Wed, 28 Dec 2022 19:39:06 +0000 (19:39 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Wed, 28 Dec 2022 21:15:04 +0000 (21:15 +0000)
doc/doc-txt/ChangeLog
src/src/dns.c
test/confs/2202
test/scripts/2200-dnsdb/2202
test/stderr/2202
test/stdout/2202

index 95c15b96b2194395348cd84392d9b94ccd59b835..ee86f52d662e4ed49a040dae37992f6cd2733ba7 100644 (file)
@@ -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
 -----------------
index 4e01d8661271948ad1b75b2378d7eb9554a28598..2355409ecce282ae7a87feedf78b15b6628215ca 100644 (file)
@@ -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");
index 825be913e7069f5f3989010058ba50ba464ad465..64c638d9a9c34f64f829b7e0c1975e6e082a1ef3 100644 (file)
@@ -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 : \
index e87087b6bc277a1a8f7182bf8d693087de5f813f..eb24fbffa3c286d718fbff9d8e983b89e6586487 100644 (file)
@@ -1,8 +1,16 @@
 # dns_again_means_nonexist
 munge dnssec
+#
+#
+#
 exim -d -bh HOSTIPV4
 helo test
 mail from:<xx@cioce.test.again.dns>
 rcpt to:<a@b>
 quit
 ****
+#
+# This used to recurse via dns_again_means_nonexist
+exim -d -DDNS_RECURSE -bh HOSTIPV4
+vrfy a@test.again.dns
+****
index f2856b01982ed65a2bf75c4c47bf5dae1560dc89..85cbb9e453bf19b836b7a175125c894aa5fdaa01 100644 (file)
@@ -34,7 +34,7 @@ log directory space = nnnnnK inodes = nnnnn check_space = 10240K inodes = 100
 SMTP>> 250 OK
 SMTP<< rcpt to:<a@b>
 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 >>>>>>>>>>>>>>>>
index f2bf2f07c8f23697bf75bf7ce0b988a7d1d3a4a0..6fcd397192e4ba31f2194927f8163877eacca97f 100644 (file)
@@ -8,3 +8,11 @@
 250 OK\r
 550 Administrative prohibition\r
 221 myhost.test.ex closing connection\r
+
+**** 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\r
+252 Administrative prohibition\r
+421 myhost.test.ex lost input connection\r