git://git.exim.org
/
exim.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
SPF: harden against crafted DNS responses
[exim.git]
/
src
/
src
/
spf.c
diff --git
a/src/src/spf.c
b/src/src/spf.c
index db6eea3a823a84be992f0bd28852a43859bed387..1981d81b630963506231c3b038bfa6ad7e5af0f7 100644
(file)
--- 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:
switch(rr_type)
{
case T_MX:
+ if (rr->size < 2) continue;
s += 2; /* skip the MX precedence field */
case T_PTR:
{
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;
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",
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;
}
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)
g = string_catn(g, s+off, chunk_len);
}
if (!g)