X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/6d9b05ae272ca2122b48451c317d601e449af932..refs/tags/exim-4.97:/src/src/spf.c diff --git a/src/src/spf.c b/src/src/spf.c index 3d83f07ba..e72051708 100644 --- a/src/src/spf.c +++ b/src/src/spf.c @@ -3,7 +3,7 @@ *************************************************/ /* SPF support. - Copyright (c) The Exim Maintainers 2015 - 2022 + Copyright (c) The Exim Maintainers 2015 - 2023 Copyright (c) Tom Kistner 2004 - 2014 License: GPL SPDX-License-Identifier: GPL-2.0-or-later @@ -71,7 +71,6 @@ SPF_dns_rr_t srr = { .hook = NULL, /* misc information */ .source = spf_dns_server }; -int dns_rc; DEBUG(D_receive) debug_printf("SPF_dns_exim_lookup '%s'\n", domain); @@ -87,20 +86,22 @@ if (rr_type == T_SPF) return spfrr; } -switch (dns_rc = dns_lookup(dnsa, US domain, rr_type, NULL)) +switch (dns_lookup(dnsa, US domain, rr_type, NULL)) { - case DNS_SUCCEED: srr.herrno = NETDB_SUCCESS; break; case DNS_AGAIN: srr.herrno = TRY_AGAIN; break; case DNS_NOMATCH: srr.herrno = HOST_NOT_FOUND; break; case DNS_NODATA: srr.herrno = NO_DATA; break; case DNS_FAIL: default: srr.herrno = NO_RECOVERY; break; + case DNS_SUCCEED: + srr.herrno = NETDB_SUCCESS; + for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; + rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) + /* Need to alloc space for all records, so no early-out */ + if (rr->type == rr_type) found++; + break; } -for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; - rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) - if (rr->type == rr_type) found++; - if (found == 0) { SPF_dns_rr_dup(&spfrr, &srr); @@ -121,6 +122,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: { @@ -136,6 +138,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", @@ -143,9 +146,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)