summaryrefslogtreecommitdiffstats
path: root/debian/patches/76-02-SPF-harden-against-crafted-DNS-responses.patch
blob: b11ef144149ea6965298c21141dee650f0c69965 (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
From 654056e44fc93a0ee7c09d1228933e8af6862206 Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Tue, 10 Oct 2023 12:45:27 +0100
Subject: [PATCH 2/3] SPF: harden against crafted DNS responses

(cherry picked from commit 4f07f38374f8662c318699fb30432273ffcfe0d3)
---
 src/spf.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/spf.c b/src/spf.c
index db6eea3a8..1981d81b6 100644
--- a/src/spf.c
+++ b/src/spf.c
@@ -116,14 +116,15 @@ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr;
     {
     const uschar * s = rr->data;
 
     srr.ttl = rr->ttl;
     switch(rr_type)
       {
       case T_MX:
+	if (rr->size < 2) continue;
 	s += 2;	/* skip the MX precedence field */
       case T_PTR:
 	{
 	uschar * buf = store_malloc(256);
 	(void)dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen, s,
 	  (DN_EXPAND_ARG4_TYPE)buf, 256);
 	s = buf;
@@ -131,24 +132,28 @@ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr;
 	}
 
       case T_TXT:
 	{
 	gstring * g = NULL;
 	uschar chunk_len;
 
+	if (rr->size < 1+6) continue;		/* min for version str */
 	if (strncmpic(rr->data+1, US SPF_VER_STR, 6) != 0)
 	  {
 	  HDEBUG(D_host_lookup) debug_printf("not an spf record: %.*s\n",
 	    (int) s[0], s+1);
 	  continue;
 	  }
 
-	for (int off = 0; off < rr->size; off += chunk_len)
+	/* require 1 byte for the chunk_len */
+	for (int off = 0; off < rr->size - 1; off += chunk_len)
 	  {
-	  if (!(chunk_len = s[off++])) break;
+	  if (  !(chunk_len = s[off++])
+	     || rr->size < off + chunk_len	/* ignore bogus size chunks */
+	     ) break;
 	  g = string_catn(g, s+off, chunk_len);
 	  }
 	if (!g)
 	  continue;
 	gstring_release_unused(g);
 	s = string_copy_malloc(string_from_gstring(g));
 	DEBUG(D_receive) debug_printf("SPF_dns_exim_lookup '%s'\n", s);
-- 
2.42.0