Fix truncated dns-lookup return record handling
authorJeremy Harris <jgh146exb@wizmail.org>
Mon, 18 May 2015 14:18:53 +0000 (15:18 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Mon, 18 May 2015 15:44:44 +0000 (16:44 +0100)
src/src/dns.c
src/src/host.c
src/src/lookups/dnsdb.c
src/src/verify.c
test/scripts/0000-Basic/0002
test/stderr/0020
test/stdout/0002

index 51029d4a557e6899b84b8e06521f07001cfbe2c1..ad98a9d4e420003bf003f64c204bac1356b70ade 100644 (file)
@@ -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 */
 
index d65da75787d7657d1cb37b5b6ff994b1b863c289..9c63cb95aeee2bee7a12426086f0c1ba9609813e 100644 (file)
@@ -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 &&
index 2e6805dc900c196be989610d88c098992f47b496..bfb0c283fd4324653741ada8e4cd7085d5ae199b 100644 (file)
@@ -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,
index 93ab9112d449233e4c010dabdf2f6a257ef21e5c..3c2942733cd3bbc9816a3c8085ad33664d56aa9e 100644 (file)
@@ -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;
index 328f5a3caa264928b6aeed6eba665accd88e91fe..acb30832419a224b3590fb1ee3735fd5cedd4864 100644 (file)
@@ -842,6 +842,7 @@ match_address:   ${if match_address{a.b.c}{a.b.c}{yes}{no}}
 ****
 # Sender host name and address etc, all unset
 exim -be
+-be Sender host name and address etc, all unset
 -oMa  sender_host_address = $sender_host_address
       sender_host_port = $sender_host_port
 -oMaa sender_host_authenticated = $sender_host_authenticated
@@ -855,6 +856,7 @@ exim -be
 ****
 # Sender host name and address etc, all set except host name.
 exim -d-all+expand -be -oMa V4NET.0.0.1.1234 -oMaa AAA -oMai philip -oMas xx@yy.zz -oMi 1.1.1.1.99 -oMr special -oMt me
+-be Sender host name and address etc, all set except host name.
 -oMa  sender_host_address = $sender_host_address
       sender_host_port = $sender_host_port
 -oMaa sender_host_authenticated = $sender_host_authenticated
@@ -867,17 +869,20 @@ exim -d-all+expand -be -oMa V4NET.0.0.1.1234 -oMaa AAA -oMai philip -oMas xx@yy.
 ****
 # Sender host name explicitly set
 exim -be -oMa V4NET.0.0.1.1234 -oMs my.host.name
+-be Sender host name explicitly set
 -oMa  sender_host_address = $sender_host_address
       sender_host_port = $sender_host_port
 -oMs  sender_host_name = $sender_host_name
 ****
 # Sender host name lookup fails (V4NET.11.12.13 is not reverse registered)
 exim -be -oMa V4NET.11.12.13
+be Sender host name lookup fails (V4NET.11.12.13 is not reverse registered)
 -oMs  sender_host_name = $sender_host_name
       host_lookup_failed = $host_lookup_failed
 ****
 # Sender host name and protocol set by Sendmail-compatible option
 exim -be -pspecial:host.name
+-be Sender host name and protocol set by Sendmail-compatible option
 -p  received_protocol = $received_protocol
 -p  sender_host_name = $sender_host_name
 ****
@@ -886,6 +891,7 @@ exim -be -pspecial:host.name
 # we are skipping. The debug output for this test will show when
 # the lookup occurs.
 exim -d-all+host_lookup+expand -be -oMa V4NET.0.0.1.1234 -oMaa AAA -oMai philip -oMas xx@yy.zz -oMi 1.1.1.1.99 -oMr special -oMt me
+-be Sender host name and address etc, all set except host name
 -oMa  sender_host_address = $sender_host_address
       sender_host_port = $sender_host_port
 -oMaa sender_host_authenticated = $sender_host_authenticated
index b5961e204bd1c401f309d36422768d10d9061f11..ee9c757d81daa7dfa9454b24bb81fdb90f0f824a 100644 (file)
@@ -67,7 +67,6 @@ MUNGED: ::1 will be omitted in what follows
 >>>   name=manyhome.test.ex address=10.250.104.60
 >>>   name=manyhome.test.ex address=10.250.104.61
 >>>   name=manyhome.test.ex address=10.250.104.62
->>>   name=manyhome.test.ex address=0.0.0.0
 >>> checking addresses for manyhome.test.ex
 >>>   10.250.104.0
 >>>   10.250.104.1
index 6c195b2691f783bc7c99d8c63fcb1510e533cd45..d145e7ec3dc2ee93e179c5ae2c675cec9941ec50 100644 (file)
@@ -787,6 +787,7 @@ xyz
 > yes
 > match_address:   no
 > 
+> -be Sender host name and address etc, all unset
 > -oMa  sender_host_address = 
 >       sender_host_port = 0
 > -oMaa sender_host_authenticated = 
@@ -798,6 +799,7 @@ xyz
 > -oMs  sender_host_name = 
 > -oMt  sender_ident = CALLER
 > 
+> -be Sender host name and address etc, all set except host name.
 > -oMa  sender_host_address = V4NET.0.0.1
 >       sender_host_port = 1234
 > -oMaa sender_host_authenticated = AAA
@@ -808,16 +810,20 @@ xyz
 > -oMr  received_protocol = special
 > -oMt  sender_ident = me
 > 
+> -be Sender host name explicitly set
 > -oMa  sender_host_address = V4NET.0.0.1
 >       sender_host_port = 1234
 > -oMs  sender_host_name = my.host.name
 > 
+> be Sender host name lookup fails (V4NET.11.12.13 is not reverse registered)
 > -oMs  sender_host_name = 
 >       host_lookup_failed = 1
 > 
+> -be Sender host name and protocol set by Sendmail-compatible option
 > -p  received_protocol = special
 > -p  sender_host_name = host.name
 > 
+> -be Sender host name and address etc, all set except host name
 > -oMa  sender_host_address = V4NET.0.0.1
 >       sender_host_port = 1234
 > -oMaa sender_host_authenticated = AAA