]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Restore localhost fallback in bin/dig/dighost.c
authorMichał Kępień <michal@isc.org>
Tue, 13 Nov 2018 13:31:18 +0000 (14:31 +0100)
committerMichał Kępień <michal@isc.org>
Tue, 13 Nov 2018 13:31:18 +0000 (14:31 +0100)
In BIND 9.11 and earlier, dig and similar tools used liblwres for
parsing /etc/resolv.conf.  After getting a list of servers from
liblwres, a tool would check the address family of each server found and
reject those unusable.  When the resulting list of usable servers was
empty, localhost addresses were queried as a fallback.

When liblwres was removed in BIND 9.12, dig and similar tools were
updated to parse /etc/resolv.conf using libirs instead.  As part of that
process, the localhost fallback was removed from bin/dig/dighost.c since
the localhost fallback built into libirs was deemed to be sufficient.
However, libirs only falls back to localhost if it does not find any
name servers at all; if it does find any valid nameserver entry in
/etc/resolv.conf, it just returns it to the caller because it is
oblivious to whether the caller supports IPv4 and/or IPv6 or not.  The
code in bin/dig/dighost.c subsequently filters the returned list of
servers in get_server_list() according to the requested address family
restrictions.  This may result in none of the addresses returned by
libirs being usable, in which case a tool will attempt to work with an
empty server list, causing a hang and subsequently a crash upon user
interruption.

Restore the localhost fallback in bin/dig/dighost.c to prevent the
aforementioned hangs and crashes and ensure recent BIND versions behave
identically to the older ones in the circumstances described above.

bin/dig/dighost.c

index 410b63435b1a2c611732bbe90ea807da40cb349d..5d35e79439d340c67dff1af9d3f57a34524df635 100644 (file)
@@ -1227,6 +1227,19 @@ create_search_list(irs_resconf_t *resconf) {
        }
 }
 
+/*%
+ * Append 'addr' to the list of servers to be queried.  This function is only
+ * called when no server addresses are explicitly specified and either libirs
+ * returns an empty list of servers to use or none of the addresses returned by
+ * libirs are usable due to the specified address family restrictions.
+ */
+static void
+add_fallback_nameserver(const char *addr) {
+       dig_server_t *server = make_server(addr, addr);
+       ISC_LINK_INIT(server, link);
+       ISC_LIST_APPEND(server_list, server, link);
+}
+
 /*%
  * Setup the system as a whole, reading key information and resolv.conf
  * settings.
@@ -1272,6 +1285,16 @@ setup_system(bool ipv4only, bool ipv6only) {
                get_server_list(resconf);
        }
 
+       /* If we don't find a nameserver fall back to localhost */
+       if (ISC_LIST_EMPTY(server_list)) {
+               if (have_ipv6) {
+                       add_fallback_nameserver("::1");
+               }
+               if (have_ipv4) {
+                       add_fallback_nameserver("127.0.0.1");
+               }
+       }
+
        irs_resconf_destroy(&resconf);
 
 #ifdef HAVE_SETLOCALE