Fix unaligned access in DNS negative-caching
[exim.git] / src / src / dns.c
index b309207cfd43dd6cf90781a71eb2ccaf6ba4b425..04cb046f465755967d703d547c10b648bd4e730a 100644 (file)
@@ -10,7 +10,6 @@
 #include "exim.h"
 
 
-
 /*************************************************
 *               Fake DNS resolver                *
 *************************************************/
@@ -619,6 +618,12 @@ Returns:     the return code
 
 /*XXX the derivation of this value needs explaining */
 #define DNS_FAILTAG_MAX 290
+#define alignment \
+  (sizeof(void *) > sizeof(double) ? sizeof(void *) : sizeof(double))
+#define align(n) \
+  (((((intptr_t)n) + (alignment-1)) / alignment) * alignment)
+#define DNS_FAILNODE_SIZE \
+  align(sizeof(tree_node) + DNS_FAILTAG_MAX + sizeof(expiring_data))
 
 static int
 dns_fail_return(const uschar * name, int type, time_t expiry, int rc)
@@ -632,11 +637,10 @@ if ((previous = tree_search(tree_dns_fails, node_name)))
   e = previous->data.ptr;
 else
   {
-  new = store_get_perm(
-    sizeof(tree_node) + DNS_FAILTAG_MAX + sizeof(expiring_data), is_tainted(name));
+  new = store_get_perm(DNS_FAILNODE_SIZE, is_tainted(name));
 
   dns_fail_tag(new->name, name, type);
-  e = (expiring_data *)((char *)new + sizeof(tree_node) + DNS_FAILTAG_MAX);
+  e = (expiring_data *) align((char *)new + sizeof(tree_node) + DNS_FAILTAG_MAX);
   new->data.ptr = e;
   (void)tree_insertnode(&tree_dns_fails, new);
   }
@@ -687,7 +691,7 @@ in the SOA.  We hope that one was returned in the lookup, and do not
 bother doing a separate lookup; if not found return a forever TTL.
 */
 
-static time_t
+time_t
 dns_expire_from_soa(dns_answer * dnsa)
 {
 const HEADER * h = (const HEADER *)dnsa->answer;
@@ -733,9 +737,9 @@ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
 
   /* Skip the SOA serial, refresh, retry & expire.  Grab the TTL */
 
-  if (p > dnsa->answer + dnsa->answerlen - 5 * NS_INT32SZ)
+  if (p > dnsa->answer + dnsa->answerlen - 5 * INT32SZ)
     break;
-  p += 4 * NS_INT32SZ;
+  p += 4 * INT32SZ;
   GETLONG(ttl, p);
 
   return time(NULL) + ttl;