summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2015-05-18 15:18:53 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2015-05-18 16:44:44 +0100
commite1a3f32f604bcdf65ac20d04ddd2bc93bc9f4deb (patch)
tree3c32a8e760debf7bc1cde6cf09b08da1f94d34fd /src
parent1fb7660fc893265f0e37ceb965396d9e005a0b74 (diff)
Fix truncated dns-lookup return record handling
Diffstat (limited to 'src')
-rw-r--r--src/src/dns.c25
-rw-r--r--src/src/host.c18
-rw-r--r--src/src/lookups/dnsdb.c2
-rw-r--r--src/src/verify.c4
4 files changed, 26 insertions, 23 deletions
diff --git a/src/src/dns.c b/src/src/dns.c
index 51029d4a5..ad98a9d4e 100644
--- a/src/src/dns.c
+++ b/src/src/dns.c
@@ -1086,31 +1086,36 @@ Argument:
dnsa the DNS answer block
rr the RR
-Returns: pointer to a chain of dns_address items
+Returns: pointer to a chain of dns_address items; NULL when the dnsa was overrun
*/
dns_address *
dns_address_from_rr(dns_answer *dnsa, dns_record *rr)
{
-dns_address *yield = NULL;
-
-dnsa = dnsa; /* Stop picky compilers warning */
+dns_address * yield = NULL;
+uschar * dnsa_lim = dnsa->answer + dnsa->answerlen;
if (rr->type == T_A)
{
uschar *p = US rr->data;
- yield = store_get(sizeof(dns_address) + 20);
- (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
- yield->next = NULL;
+ if (p + 4 <= dnsa_lim)
+ {
+ yield = store_get(sizeof(dns_address) + 20);
+ (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ yield->next = NULL;
+ }
}
#if HAVE_IPV6
else
{
- yield = store_get(sizeof(dns_address) + 50);
- inet_ntop(AF_INET6, US rr->data, CS yield->address, 50);
- yield->next = NULL;
+ if (rr->data + 16 <= dnsa_lim)
+ {
+ yield = store_get(sizeof(dns_address) + 50);
+ inet_ntop(AF_INET6, US rr->data, CS yield->address, 50);
+ yield->next = NULL;
+ }
}
#endif /* HAVE_IPV6 */
diff --git a/src/src/host.c b/src/src/host.c
index d65da7578..9c63cb95a 100644
--- a/src/src/host.c
+++ b/src/src/host.c
@@ -251,11 +251,10 @@ else
}
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
+ rr;
rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
- {
- if (rr->type == type) count++;
- }
+ if (rr->type == type)
+ count++;
yield = store_get(sizeof(struct hostent));
alist = store_get((count + 1) * sizeof(char **));
@@ -268,14 +267,14 @@ else
yield->h_addr_list = CSS alist;
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
+ rr;
rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
{
int i, n;
int x[4];
dns_address *da;
if (rr->type != type) continue;
- da = dns_address_from_rr(&dnsa, rr);
+ if (!(da = dns_address_from_rr(&dnsa, rr))) break;
*alist++ = adds;
n = host_aton(da->address, x);
for (i = 0; i < n; i++)
@@ -2356,7 +2355,7 @@ for (; i >= 0; i--)
fully_qualified_name = NULL;
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
+ rr;
rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
{
if (rr->type == type)
@@ -2368,15 +2367,14 @@ for (; i >= 0; i--)
DEBUG(D_host_lookup)
{
- if (da == NULL)
- debug_printf("no addresses extracted from A6 RR for %s\n",
+ if (!da) debug_printf("no addresses extracted from A6 RR for %s\n",
host->name);
}
/* This loop runs only once for A and AAAA records, but may run
several times for an A6 record that generated multiple addresses. */
- for (; da != NULL; da = da->next)
+ for (; da; da = da->next)
{
#ifndef STAND_ALONE
if (ignore_target_hosts != NULL &&
diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c
index 2e6805dc9..bfb0c283f 100644
--- a/src/src/lookups/dnsdb.c
+++ b/src/src/lookups/dnsdb.c
@@ -391,7 +391,7 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
if (type == T_A || type == T_AAAA || type == T_ADDRESSES)
{
dns_address *da;
- for (da = dns_address_from_rr(&dnsa, rr); da != NULL; da = da->next)
+ for (da = dns_address_from_rr(&dnsa, rr); da; da = da->next)
{
if (ptr != 0) yield = string_cat(yield, &size, &ptr, outsep, 1);
yield = string_cat(yield, &size, &ptr, da->address,
diff --git a/src/src/verify.c b/src/src/verify.c
index 93ab9112d..3c2942733 100644
--- a/src/src/verify.c
+++ b/src/src/verify.c
@@ -3620,13 +3620,13 @@ if (t == NULL)
dns_record *rr;
dns_address **addrp = &(cb->rhs);
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
+ rr;
rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
{
if (rr->type == T_A)
{
dns_address *da = dns_address_from_rr(&dnsa, rr);
- if (da != NULL)
+ if (da)
{
*addrp = da;
while (da->next != NULL) da = da->next;