chiark / gitweb /
src/types.c: Do not crash when one of several addr subqueries fails
authorIan Jackson <>
Thu, 19 Feb 2015 01:05:33 +0000 (01:05 +0000)
committerIan Jackson <>
Sat, 21 Feb 2015 11:41:46 +0000 (11:41 +0000)
If a name passed to the addr lookup machinery (eg, passed to an
adns_r_addr query, or resulting from a dereferencing query like
adns_r_mx) has addresses for one address family (eg IPv4) but
temporary failure for another (eg IPv6) then adns might (would
usually) crash.

This is because icb_hostaddr would fail to reset the accumulated addrs
pointer to 0 after freeing it, and then set naddrs to -1.  The crash
would occur in makefinal, which would attempt to arrange to copy -1
elements into the unifed output buffer.

If the second AF gives a permanent error, the relevant part of the
answer would contain an invalid (freed) pointer, with a zero length.
The result during makefinal_query would be to allocate a zero length
`block' in the unified output result buffer and put the pointer to
that in the answer for the application, which is a violation of the
promised API.

This bug was introduced with IPv6 support (in 1.5.0, in commit

A test case for this bug will be introduced shortly.

Reported-by: Chris Burton of
Signed-off-by: Ian Jackson <>

index 77eda68..41ef965 100644 (file)
--- a/changelog
+++ b/changelog
@@ -6,6 +6,12 @@ adns (1.5.1~~) unstable; urgency=low
   * Fix TCP async connect handling.  The bug is hidden on Linux and on most
     systems where the nameserver is on localhost.  If it is not hidden,
     adns's TCP support is broken unless adns_if_noautosys is used.
+  * Fix addr queries (including subqueries, ie including deferencing MX
+    lookups etc.) not to crash when one of the address queries returns
+    tempfail.  Also, do not return a spurious pointer to the application
+    when one of the address queries returns a permanent error (although,
+    the application almost certainly won't use this pointer because the
+    associated count is zero).
index d65e155..142a942 100644 (file)
@@ -892,6 +892,7 @@ static void icb_hostaddr(adns_query parent, adns_query child) {
   if (st) {
     adns__free_interim(parent, rrp->addrs);
+    rrp->addrs = 0;
     rrp->naddrs= (st>0 && st<=adns_s_max_tempfail) ? -1 : 0;