*************************************************/
/* SPF support.
- Copyright (c) The Exim Maintainers 2015 - 2022
+ Copyright (c) The Exim Maintainers 2015 - 2023
Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004 - 2014
License: GPL
SPDX-License-Identifier: GPL-2.0-or-later
srr.herrno = NETDB_SUCCESS;
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++; break; }
+ /* Need to alloc space for all records, so no early-out */
+ if (rr->type == rr_type) found++;
break;
}
switch(rr_type)
{
case T_MX:
+ if (rr->size < 2) continue;
s += 2; /* skip the MX precedence field */
case T_PTR:
{
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",
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)
Return: OK/FAIL */
int
-spf_process(const uschar **listptr, uschar *spf_envelope_sender, int action)
+spf_process(const uschar ** listptr, const uschar * spf_envelope_sender,
+ int action)
{
int sep = 0;
const uschar *list = *listptr;