Fix recursion on dns_again_means_nonexist. Bug 2911
[exim.git] / src / src / dns.c
index 8bf7f65424dea6faeaeff8e21ce8f83f6bdc1519..2355409ecce282ae7a87feedf78b15b6628215ca 100644 (file)
@@ -2,9 +2,10 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
+/* Copyright (c) The Exim Maintainers 2020 - 2022 */
 /* Copyright (c) University of Cambridge 1995 - 2018 */
-/* Copyright (c) The Exim Maintainers 2020 - 2021 */
 /* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
 
 /* Functions for interfacing with the DNS. */
 
@@ -258,7 +259,7 @@ else
   {
   int v6[4];
 
-  g = string_get_tainted(32, is_tainted(string));
+  g = string_get_tainted(32, string);
   (void)host_aton(string, v6);
 
   /* The original specification for IPv6 reverse lookup was to invert each
@@ -637,7 +638,7 @@ if ((previous = tree_search(tree_dns_fails, node_name)))
   e = previous->data.ptr;
 else
   {
-  e = store_get_perm(DNS_FAILNODE_SIZE, is_tainted(name));
+  e = store_get_perm(DNS_FAILNODE_SIZE, name);
   new = (void *)(e+1);
   dns_fail_tag(new->name, name, type);
   new->data.ptr = e;
@@ -801,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
@@ -905,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");
@@ -1065,7 +1078,7 @@ for (int i = 0; i <= dns_cname_loops; i++)
     return DNS_FAIL;
 
   /* DNS data comes from the outside, hence tainted */
-  data = store_get(256, TRUE);
+  data = store_get(256, GET_TAINTED);
   if (dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen,
       cname_rr.data, (DN_EXPAND_ARG4_TYPE)data, 256) < 0)
     return DNS_FAIL;
@@ -1148,7 +1161,7 @@ switch (type)
   case T_CSA:
     {
     uschar *srvname, *namesuff, *tld;
-    int priority, weight, port;
+    int priority, dummy_weight, port;
     int limit, rc, i;
     BOOL ipv6;
     dns_record *rr;
@@ -1237,7 +1250,7 @@ switch (type)
 
        /* Extract the numerical SRV fields (p is incremented) */
        GETSHORT(priority, p);
-       GETSHORT(weight, p);
+       GETSHORT(dummy_weight, p);
        GETSHORT(port, p);
 
        /* Check the CSA version number */
@@ -1293,7 +1306,7 @@ if (rr->type == T_A)
   if (p + 4 <= dnsa_lim)
     {
     /* the IP is not regarded as tainted */
-    yield = store_get(sizeof(dns_address) + 20, FALSE);
+    yield = store_get(sizeof(dns_address) + 20, GET_UNTAINTED);
     (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
     yield->next = NULL;
     }
@@ -1307,7 +1320,7 @@ else
     {
     struct in6_addr in6;
     for (int i = 0; i < 16; i++) in6.s6_addr[i] = rr->data[i];
-    yield = store_get(sizeof(dns_address) + 50, FALSE);
+    yield = store_get(sizeof(dns_address) + 50, GET_UNTAINTED);
     inet_ntop(AF_INET6, &in6, CS yield->address, 50);
     yield->next = NULL;
     }
@@ -1324,7 +1337,7 @@ dns_pattern_init(void)
 {
 if (check_dns_names_pattern[0] != 0 && !regex_check_dns_names)
   regex_check_dns_names =
-    regex_must_compile(check_dns_names_pattern, FALSE, TRUE);
+    regex_must_compile(check_dns_names_pattern, MCS_NOFLAGS, TRUE);
 }
 
 /* vi: aw ai sw=2