]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
4651. [bug] Nsupdate could attempt to use a zeroed address on
authorMark Andrews <marka@isc.org>
Wed, 19 Jul 2017 05:35:41 +0000 (15:35 +1000)
committerMark Andrews <marka@isc.org>
Wed, 19 Jul 2017 05:36:41 +0000 (15:36 +1000)
                        server timeout. [RT #45417]

(cherry picked from commit dac36869f3ec3a097eddc393a050c804f72ce5b7)

bin/nsupdate/nsupdate.c
bin/tests/system/nsupdate/tests.sh

index bd1200f07aeaee66fd5004bfb06ba911e6fd6b7b..2ef75905a26320e0acc93b475a00a2facb4afd7a 100644 (file)
@@ -165,7 +165,9 @@ static isc_boolean_t default_servers = ISC_TRUE;
 static int ns_inuse = 0;
 static int master_inuse = 0;
 static int ns_total = 0;
+static int ns_alloc = 0;
 static int master_total = 0;
+static int master_alloc = 0;
 static isc_sockaddr_t *localaddr4 = NULL;
 static isc_sockaddr_t *localaddr6 = NULL;
 static const char *keyfile = NULL;
@@ -306,9 +308,10 @@ master_from_servers(void) {
 
        if (master_servers != NULL && master_servers != servers)
                isc_mem_put(gmctx, master_servers,
-                           master_total * sizeof(isc_sockaddr_t));
+                           master_alloc * sizeof(isc_sockaddr_t));
        master_servers = servers;
        master_total = ns_total;
+       master_alloc = ns_alloc;
        master_inuse = ns_inuse;
 }
 
@@ -750,10 +753,10 @@ doshutdown(void) {
         */
        if (master_servers != NULL && master_servers != servers)
                isc_mem_put(gmctx, master_servers,
-                           master_total * sizeof(isc_sockaddr_t));
+                           master_alloc * sizeof(isc_sockaddr_t));
 
        if (servers != NULL)
-               isc_mem_put(gmctx, servers, ns_total * sizeof(isc_sockaddr_t));
+               isc_mem_put(gmctx, servers, ns_alloc * sizeof(isc_sockaddr_t));
 
        if (localaddr4 != NULL)
                isc_mem_put(gmctx, localaddr4, sizeof(isc_sockaddr_t));
@@ -868,7 +871,7 @@ setup_system(void) {
        if (servers != NULL) {
                if (master_servers == servers)
                        master_servers = NULL;
-               isc_mem_put(gmctx, servers, ns_total * sizeof(isc_sockaddr_t));
+               isc_mem_put(gmctx, servers, ns_alloc * sizeof(isc_sockaddr_t));
        }
 
        ns_inuse = 0;
@@ -881,8 +884,8 @@ setup_system(void) {
 
                default_servers = !local_only;
 
-               ns_total = (have_ipv4 ? 1 : 0) + (have_ipv6 ? 1 : 0);
-               servers = isc_mem_get(gmctx, ns_total * sizeof(isc_sockaddr_t));
+               ns_total = ns_alloc = (have_ipv4 ? 1 : 0) + (have_ipv6 ? 1 : 0);
+               servers = isc_mem_get(gmctx, ns_alloc * sizeof(isc_sockaddr_t));
                if (servers == NULL)
                        fatal("out of memory");
 
@@ -897,8 +900,8 @@ setup_system(void) {
                                             &in6, dnsport);
                }
        } else {
-               ns_total = lwconf->nsnext;
-               servers = isc_mem_get(gmctx, ns_total * sizeof(isc_sockaddr_t));
+               ns_total = ns_alloc = lwconf->nsnext;
+               servers = isc_mem_get(gmctx, ns_alloc * sizeof(isc_sockaddr_t));
                if (servers == NULL)
                        fatal("out of memory");
                for (i = 0; i < ns_total; i++) {
@@ -990,7 +993,7 @@ setup_system(void) {
                setup_keyfile(gmctx, glctx);
 }
 
-static void
+static int
 get_addresses(char *host, in_port_t port,
              isc_sockaddr_t *sockaddr, int naddrs)
 {
@@ -1003,6 +1006,7 @@ get_addresses(char *host, in_port_t port,
        if (result != ISC_R_SUCCESS)
                fatal("couldn't get address for '%s': %s",
                      host, isc_result_totext(result));
+       return (count);
 }
 
 static void
@@ -1465,19 +1469,19 @@ evaluate_server(char *cmdline) {
        if (servers != NULL) {
                if (master_servers == servers)
                        master_servers = NULL;
-               isc_mem_put(gmctx, servers, ns_total * sizeof(isc_sockaddr_t));
+               isc_mem_put(gmctx, servers, ns_alloc * sizeof(isc_sockaddr_t));
        }
 
        default_servers = ISC_FALSE;
 
-       ns_total = MAX_SERVERADDRS;
+       ns_alloc = MAX_SERVERADDRS;
        ns_inuse = 0;
-       servers = isc_mem_get(gmctx, ns_total * sizeof(isc_sockaddr_t));
+       servers = isc_mem_get(gmctx, ns_alloc * sizeof(isc_sockaddr_t));
        if (servers == NULL)
                fatal("out of memory");
 
-       memset(servers, 0, ns_total * sizeof(isc_sockaddr_t));
-       get_addresses(server, (in_port_t)port, servers, ns_total);
+       memset(servers, 0, ns_alloc * sizeof(isc_sockaddr_t));
+       ns_total = get_addresses(server, (in_port_t)port, servers, ns_alloc);
 
        return (STATUS_MORE);
 }
@@ -2508,7 +2512,7 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
                                                FIND_TIMEOUT, 3,
                                                global_task, recvsoa, reqinfo,
                                                &request);
-               check_result(result, "dns_request_createvia");
+               check_result(result, "dns_request_createvia3");
                requests++;
                return;
        }
@@ -2622,15 +2626,16 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
 
                if (master_servers != NULL && master_servers != servers)
                        isc_mem_put(gmctx, master_servers,
-                                   master_total * sizeof(isc_sockaddr_t));
-               master_total = MAX_SERVERADDRS;
-               size = master_total * sizeof(isc_sockaddr_t);
+                                   master_alloc * sizeof(isc_sockaddr_t));
+               master_alloc = MAX_SERVERADDRS;
+               size = master_alloc * sizeof(isc_sockaddr_t);
                master_servers = isc_mem_get(gmctx, size);
                if (master_servers == NULL)
                        fatal("out of memory");
 
                memset(master_servers, 0, size);
-               get_addresses(serverstr, dnsport, master_servers, master_total);
+               master_total = get_addresses(serverstr, dnsport,
+                                            master_servers, master_alloc);
                master_inuse = 0;
        } else
                master_from_servers();
@@ -2701,7 +2706,7 @@ sendrequest(isc_sockaddr_t *destaddr, dns_message_t *msg,
                                        default_servers ? NULL : tsigkey,
                                        FIND_TIMEOUT * 20, FIND_TIMEOUT, 3,
                                        global_task, recvsoa, reqinfo, request);
-       check_result(result, "dns_request_createvia");
+       check_result(result, "dns_request_createvia3");
        requests++;
 }
 
index 762044096760c20dff0007e76ca2af8f7111ac50..fad22b1104aed1f80ada245084e6496f4ae3f8f5 100755 (executable)
@@ -196,6 +196,7 @@ grep "status: NOERROR" dig.out.ns1.$n > /dev/null || ret=1
 [ $ret = 0 ] || { echo I:failed; status=1; }
 
 n=`expr $n + 1`
+ret=0
 echo "I:check that TYPE=0 additional data is handled ($n)"
 echo "a0e4280000010000000000010000060001c00c000000fe000000000000" |
 $PERL ../packet.pl -a 10.53.0.1 -p 5300 -t tcp > /dev/null
@@ -204,6 +205,7 @@ grep "status: NOERROR" dig.out.ns1.$n > /dev/null || ret=1
 [ $ret = 0 ] || { echo I:failed; status=1; }
 
 n=`expr $n + 1`
+ret=0
 echo "I:check that update to undefined class is handled ($n)"
 echo "a0e4280000010001000000000000060101c00c000000fe000000000000" |
 $PERL ../packet.pl -a 10.53.0.1 -p 5300 -t tcp > /dev/null
@@ -212,6 +214,7 @@ grep "status: NOERROR" dig.out.ns1.$n > /dev/null || ret=1
 [ $ret = 0 ] || { echo I:failed; status=1; }
 
 n=`expr $n + 1`
+ret=0
 echo "I:check that address family mismatch is handled ($n)"
 $NSUPDATE <<END > /dev/null 2>&1 && ret=1
 server ::1
@@ -223,6 +226,7 @@ END
 
 
 n=`expr $n + 1`
+ret=0
 echo "I:check that unixtime serial number is correctly generated ($n)"
 oldserial=`$DIG +short unixtime.nil. soa @10.53.0.1 -p 5300 | awk '{print $3}'` || ret=1
 $NSUPDATE <<END > /dev/null 2>&1 || ret=1
@@ -254,6 +258,7 @@ $DIG +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil.\
        @10.53.0.1 axfr -p 5300 > dig.out.ns1 || ret=1
 [ $ret = 0 ] || { echo I:failed; status=1; }
 
+ret=0
 echo "I:fetching second copy of test zone"
 $DIG +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil.\
        @10.53.0.2 axfr -p 5300 > dig.out.ns2 || ret=1
@@ -432,6 +437,7 @@ if [ $ret != 0 ] ; then echo "I: failed"; status=`expr $ret + $status`; fi
 
 
 
+ret=0
 echo "I:testing that rndc stop updates the master file"
 $NSUPDATE -k ns1/ddns.key <<END > /dev/null || ret=1
 server 10.53.0.1 5300
@@ -740,10 +746,24 @@ grep "status: NXDOMAIN" dig.out.ns3.test$n > /dev/null || ret=1
 grep "records in zone (4) exceeds max-records (3)" ns3/named.run > /dev/null || ret=1
 [ $ret = 0 ] || { echo I:failed; status=1; }
 
+n=`expr $n + 1`
+ret=0
+echo "I:check whether valid addresses are used for master failover ($n)"
+$NSUPDATE -t 1 <<END > nsupdate.out-$n 2>&1 && ret=1
+server 10.53.0.4 5300
+zone unreachable.
+update add unreachable. 600 A 192.0.2.1
+send
+END
+grep "; Communication with 10.53.0.4#5300 failed: timed out" nsupdate.out-$n > /dev/null 2>&1 || ret=1
+grep "not implemented" nsupdate.out-$n > /dev/null 2>&1 && ret=1
+[ $ret = 0 ] || { echo I:failed; status=1; }
+
 #
 #  Add client library tests here
 #
 n=`expr $n + 1`
+ret=0
 echo "I:check that dns_client_update handles prerequisite NXDOMAIN failure ($n)"
 $SAMPLEUPDATE -P 5300 -a 10.53.0.1 -a 10.53.0.2 -p "nxdomain exists.sample" \
        add "nxdomain-exists.sample 0 in a 1.2.3.4" > update.out.test$n 2>&1
@@ -760,6 +780,7 @@ grep "status: NOERROR" check.out.ns2.test$n > /dev/null || ret=1
 [ $ret = 0 ] || { echo I:failed; status=1; }
 
 n=`expr $n + 1`
+ret=0
 echo "I:check that dns_client_update handles prerequisite YXDOMAIN failure ($n)"
 $SAMPLEUPDATE -P 5300 -a 10.53.0.1 -a 10.53.0.2 -p "yxdomain nxdomain.sample" \
        add "yxdomain-nxdomain.sample 0 in a 1.2.3.4" > update.out.test$n 2>&1
@@ -776,6 +797,7 @@ grep "status: NOERROR" check.out.ns2.test$n > /dev/null || ret=1
 [ $ret = 0 ] || { echo I:failed; status=1; }
 
 n=`expr $n + 1`
+ret=0
 echo "I:check that dns_client_update handles prerequisite NXRRSET failure ($n)"
 $SAMPLEUPDATE -P 5300 -a 10.53.0.1 -a 10.53.0.2 -p "nxrrset exists.sample TXT This RRset exists." \
        add "nxrrset-exists.sample 0 in a 1.2.3.4" > update.out.test$n 2>&1
@@ -792,6 +814,7 @@ grep "status: NOERROR" check.out.ns2.test$n > /dev/null || ret=1
 [ $ret = 0 ] || { echo I:failed; status=1; }
 
 n=`expr $n + 1`
+ret=0
 echo "I:check that dns_client_update handles prerequisite YXRRSET failure ($n)"
 $SAMPLEUPDATE -s -P 5300 -a 10.53.0.1 -a 10.53.0.2 \
        -p "yxrrset no-txt.sample TXT" \