Fix unaligned access in DNS negative-caching
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 8 Sep 2019 11:11:16 +0000 (12:11 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 8 Sep 2019 11:11:16 +0000 (12:11 +0100)
src/src/dns.c

index ece6524d60d877a017e1de8978ca7403fa54a225..04cb046f465755967d703d547c10b648bd4e730a 100644 (file)
@@ -618,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)
@@ -631,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);
   }