summaryrefslogtreecommitdiffstats
path: root/debian/patches/75_55-Fix-recursion-on-dns_again_means_nonexist.-Bug-2911.patch
blob: bbbfbe9ef1e7179db03aeb619a271448aa033669 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
From 1d38781da934809e6ce0b8c3718c4b3bccdfe1d2 Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Wed, 28 Dec 2022 19:39:06 +0000
Subject: [PATCH] Fix recursion on dns_again_means_nonexist. Bug 2911

---
 doc/ChangeLog        |  8 +++++
 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(-)

--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -33,10 +33,18 @@ JH/14 Bug 2933: Fix regex substring matc
 JH/18 Fix a fencepost error in logging.  Previously (since 4.92) when a log line
       was exactly sized compared to the log buffer, a crash occurred with the
       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
 -----------------
 
--- a/src/dns.c
+++ b/src/dns.c
@@ -799,10 +799,11 @@ int
 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
 a timeout on one domain doesn't happen time and time again for messages that
 have many addresses in the same domain. We rely on the resolver and name server
@@ -903,15 +904,26 @@ if (dnsa->answerlen < 0) switch (h_errno
     DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave TRY_AGAIN\n",
       name, dns_text_type(type));
 
     /* 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");
       return dns_fail_return(name, type, 0, DNS_AGAIN);
       }