Harden dnsdb against crafted DNS responses. Bug 3033
[exim.git] / src / src / dns.c
index 7d7ee0c0460584022028723c4f09a381908a597a..8dc3695a118782926b1ec994997f2dfc420a5acb 100644 (file)
@@ -304,7 +304,7 @@ Return: TRUE for a bad result
 static BOOL
 dnss_inc_aptr(const dns_answer * dnsa, dns_scan * dnss, unsigned delta)
 {
-return (dnss->aptr += delta) >= dnsa->answer + dnsa->answerlen;
+return (dnss->aptr += delta) > dnsa->answer + dnsa->answerlen;
 }
 
 /*************************************************
@@ -388,7 +388,7 @@ if (reset != RESET_NEXT)
       TRACE trace = "A-hdr";
       if (dnss_inc_aptr(dnsa, dnss, namelen+8)) goto null_return;
       GETSHORT(dnss->srr.size, dnss->aptr); /* size of data portion */
-      /* skip over it */
+      /* skip over it, checking for a bogus size */
       TRACE trace = "A-skip";
       if (dnss_inc_aptr(dnsa, dnss, dnss->srr.size)) goto null_return;
       }
@@ -428,10 +428,9 @@ GETLONG(dnss->srr.ttl, dnss->aptr);                /* TTL */
 GETSHORT(dnss->srr.size, dnss->aptr);          /* Size of data portion */
 dnss->srr.data = dnss->aptr;                   /* The record's data follows */
 
-/* Unchecked increment ok here since no further access on this iteration;
-will be checked on next at "R-name". */
-
-dnss->aptr += dnss->srr.size;                  /* Advance to next RR */
+/* skip over it, checking for a bogus size */
+if (dnss_inc_aptr(dnsa, dnss, dnss->srr.size))
+  goto null_return;
 
 /* Return a pointer to the dns_record structure within the dns_answer. This is
 for convenience so that the scans can use nice-looking for loops. */