summaryrefslogtreecommitdiffstats
path: root/debian/patches/76-02-SPF-harden-against-crafted-DNS-responses.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/76-02-SPF-harden-against-crafted-DNS-responses.patch')
-rw-r--r--debian/patches/76-02-SPF-harden-against-crafted-DNS-responses.patch64
1 files changed, 64 insertions, 0 deletions
diff --git a/debian/patches/76-02-SPF-harden-against-crafted-DNS-responses.patch b/debian/patches/76-02-SPF-harden-against-crafted-DNS-responses.patch
new file mode 100644
index 0000000..b11ef14
--- /dev/null
+++ b/debian/patches/76-02-SPF-harden-against-crafted-DNS-responses.patch
@@ -0,0 +1,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
+