From 654056e44fc93a0ee7c09d1228933e8af6862206 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Tue, 10 Oct 2023 12:45:27 +0100 Subject: [PATCH] SPF: harden against crafted DNS responses (cherry picked from commit 4f07f38374f8662c318699fb30432273ffcfe0d3) --- src/src/spf.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/src/spf.c b/src/src/spf.c index db6eea3a8..1981d81b6 100644 --- a/src/src/spf.c +++ b/src/src/spf.c @@ -120,6 +120,7 @@ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; switch(rr_type) { case T_MX: + if (rr->size < 2) continue; s += 2; /* skip the MX precedence field */ case T_PTR: { @@ -135,6 +136,7 @@ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; 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", @@ -142,9 +144,12 @@ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; 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) -- 2.30.2