From d0803df3310ad09447c34b972e7594d576f5cbb5 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Thu, 30 Jan 2014 17:03:32 -0800 Subject: [PATCH] [master] fixed geoip in blackhole ACLs 3722. [bug] Using geoip ACLs in a blackhole statement could cause a segfault. [RT #35272] --- CHANGES | 3 ++ bin/named/geoip.c | 1 - bin/tests/system/geoip/clean.sh | 2 +- bin/tests/system/geoip/ns2/named12.conf | 45 +++++++++++++++++++++++++ bin/tests/system/geoip/tests.sh | 13 +++++++ configure | 2 +- configure.in | 2 +- lib/dns/acl.c | 2 ++ lib/dns/geoip.c | 3 +- lib/dns/include/dns/acl.h | 4 +++ 10 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 bin/tests/system/geoip/ns2/named12.conf diff --git a/CHANGES b/CHANGES index 6c243a811a..369b314ca3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3722. [bug] Using geoip ACLs in a blackhole statement + could cause a segfault. [RT #35272] + 3721. [doc] Improved doucmentation of the EDNS processing enhancements introduced in change #3593. [RT #35275] diff --git a/bin/named/geoip.c b/bin/named/geoip.c index 4f2f47f91e..3a9ab1b68c 100644 --- a/bin/named/geoip.c +++ b/bin/named/geoip.c @@ -101,7 +101,6 @@ ns_geoip_load(char *dir) { return; #else GeoIPOptions method; - GeoIPDBTypes edition; #ifdef _WIN32 method = GEOIP_STANDARD; diff --git a/bin/tests/system/geoip/clean.sh b/bin/tests/system/geoip/clean.sh index e3397a7c7d..96409f0112 100644 --- a/bin/tests/system/geoip/clean.sh +++ b/bin/tests/system/geoip/clean.sh @@ -16,4 +16,4 @@ rm -f ns2/named.conf rm -f ns2/example[1234567].db -rm -f dig.out.* +rm -f dig.out.* rndc.out.* diff --git a/bin/tests/system/geoip/ns2/named12.conf b/bin/tests/system/geoip/ns2/named12.conf new file mode 100644 index 0000000000..b7fda1249e --- /dev/null +++ b/bin/tests/system/geoip/ns2/named12.conf @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +// NS2 + +controls { /* empty */ }; + +acl blocking { + geoip db country country AU; +}; + +options { + query-source address 10.53.0.2; + notify-source 10.53.0.2; + transfer-source 10.53.0.2; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.2; }; + listen-on-v6 { none; }; + recursion no; + geoip-directory "../data"; + blackhole { blocking; }; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; +}; diff --git a/bin/tests/system/geoip/tests.sh b/bin/tests/system/geoip/tests.sh index 2f831f20c3..51b1c4c288 100644 --- a/bin/tests/system/geoip/tests.sh +++ b/bin/tests/system/geoip/tests.sh @@ -229,5 +229,18 @@ done [ $ret -eq 0 ] || echo "I:failed" status=`expr $status + $ret` +echo "I:reloading server" +cp -f ns2/named12.conf ns2/named.conf +$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /' +sleep 3 + +n=`expr $n + 1` +echo "I:checking GeoIP blackhole ACL" +ret=0 +$DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n || ret=1 +$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 status 2>&1 > rndc.out.ns2.test$n || ret=1 +[ $ret -eq 0 ] || echo "I:failed" +status=`expr $status + $ret` + echo "I:exit status: $status" exit $status diff --git a/configure b/configure index 3a1d771744..07f0f77f29 100755 --- a/configure +++ b/configure @@ -13470,7 +13470,7 @@ fi if test "$use_geoip" = "yes" then - for d in /usr /usr/local + for d in /usr /usr/local /opt/local do if test -f $d/include/GeoIP.h then diff --git a/configure.in b/configure.in index cbb8cca356..ed69c6a8aa 100644 --- a/configure.in +++ b/configure.in @@ -605,7 +605,7 @@ AC_ARG_WITH(geoip, if test "$use_geoip" = "yes" then - for d in /usr /usr/local + for d in /usr /usr/local /opt/local do if test -f $d/include/GeoIP.h then diff --git a/lib/dns/acl.c b/lib/dns/acl.c index c35f2387e2..fc5598503a 100644 --- a/lib/dns/acl.c +++ b/lib/dns/acl.c @@ -408,6 +408,8 @@ dns_aclelement_match(const isc_netaddr_t *reqaddr, #ifdef HAVE_GEOIP case dns_aclelementtype_geoip: + if (env == NULL || env->geoip == NULL) + return (ISC_FALSE); return (dns_geoip_match(reqaddr, env->geoip, &e->geoip_elem)); #endif default: diff --git a/lib/dns/geoip.c b/lib/dns/geoip.c index 1f55962cbf..5de5fa160e 100644 --- a/lib/dns/geoip.c +++ b/lib/dns/geoip.c @@ -249,8 +249,9 @@ country_lookup(GeoIP *db, dns_geoip_subtype_t subtype, if (prev_state != NULL && prev_state->subtype == subtype && + prev_state->family == family && ((prev_state->family == AF_INET && prev_state->ipnum == ipnum) || - (prev_state->family == AF_INET6 && + (prev_state->family == AF_INET6 && ipnum6 != NULL && memcmp(prev_state->ipnum6.s6_addr, ipnum6->s6_addr, 16) == 0))) text = prev_state->text; diff --git a/lib/dns/include/dns/acl.h b/lib/dns/include/dns/acl.h index f6b1e44caf..76a6bb1e1d 100644 --- a/lib/dns/include/dns/acl.h +++ b/lib/dns/include/dns/acl.h @@ -230,6 +230,10 @@ dns_acl_match(const isc_netaddr_t *reqaddr, * and 'matchelt' is non-NULL, *matchelt will be pointed to the matching * element. * + * 'env' points to the current ACL environment, including the + * current values of localhost and localnets and (if applicable) + * the GeoIP context. + * * Returns: *\li #ISC_R_SUCCESS Always succeeds. */