From b2b3882c5c0dfe7d0daa56ef76b2ab7f927de3f3 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 4 Nov 2014 12:34:12 +1100 Subject: [PATCH] 3998. [bug] isc_radix_search was returning matches that were to precise. [RT #37680] (cherry picked from commit b976c39c07f7672bd1293e878b3306c7decf8afe) --- CHANGES | 3 ++ lib/isc/radix.c | 3 ++ lib/isc/tests/Makefile.in | 8 +++- lib/isc/tests/radix_test.c | 95 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 lib/isc/tests/radix_test.c diff --git a/CHANGES b/CHANGES index b32b30d60f..7089d36ceb 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3998. [bug] isc_radix_search was returning matches that were + to precise. [RT #37680] + 3997. [protocol] Add OPENGPGKEY record. [RT# 37671] 3996. [bug] Address use after free on out of memory error in diff --git a/lib/isc/radix.c b/lib/isc/radix.c index df26615fa9..1367def320 100644 --- a/lib/isc/radix.c +++ b/lib/isc/radix.c @@ -279,6 +279,9 @@ isc_radix_search(isc_radix_tree_t *radix, isc_radix_node_t **target, while (cnt-- > 0) { node = stack[cnt]; + if (prefix->bitlen < node->bit) + continue; + if (_comp_with_mask(isc_prefix_tochar(node->prefix), isc_prefix_tochar(prefix), node->prefix->bitlen)) { diff --git a/lib/isc/tests/Makefile.in b/lib/isc/tests/Makefile.in index 5685784c55..47c5765d79 100644 --- a/lib/isc/tests/Makefile.in +++ b/lib/isc/tests/Makefile.in @@ -36,14 +36,14 @@ LIBS = @LIBS@ @ATFLIBS@ OBJS = isctest.@O@ SRCS = isctest.c taskpool_test.c socket_test.c hash_test.c \ - lex_test.c \ + lex_test.c radix_test.c \ sockaddr_test.c symtab_test.c task_test.c queue_test.c \ parse_test.c pool_test.c print_test.c regex_test.c \ socket_test.c safe_test.c time_test.c aes_test.c SUBDIRS = TARGETS = taskpool_test@EXEEXT@ socket_test@EXEEXT@ hash_test@EXEEXT@ \ - lex_test@EXEEXT@ \ + lex_test@EXEEXT@ radix_test@EXEEXT@ \ sockaddr_test@EXEEXT@ symtab_test@EXEEXT@ task_test@EXEEXT@ \ queue_test@EXEEXT@ parse_test@EXEEXT@ pool_test@EXEEXT@ \ print_test@EXEEXT@ regex_test@EXEEXT@ socket_test@EXEEXT@ \ @@ -75,6 +75,10 @@ queue_test@EXEEXT@: queue_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ queue_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} +radix_test@EXEEXT@: radix_test.@O@ isctest.@O@ ${ISCDEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ + radix_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} + symtab_test@EXEEXT@: symtab_test.@O@ isctest.@O@ ${ISCDEPLIBS} ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ symtab_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS} diff --git a/lib/isc/tests/radix_test.c b/lib/isc/tests/radix_test.c new file mode 100644 index 0000000000..c0fc7035f1 --- /dev/null +++ b/lib/isc/tests/radix_test.c @@ -0,0 +1,95 @@ +/* + * 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. + */ + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "isctest.h" + +ATF_TC(isc_radix_search); +ATF_TC_HEAD(isc_radix_search, tc) { + atf_tc_set_md_var(tc, "descr", "test radix seaching"); +} +ATF_TC_BODY(isc_radix_search, tc) { + isc_radix_tree_t *radix = NULL; + isc_radix_node_t *node; + isc_prefix_t prefix; + isc_result_t result; + struct in_addr in_addr; + isc_netaddr_t netaddr; + + UNUSED(tc); + + result = isc_test_begin(NULL, ISC_TRUE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + result = isc_radix_create(mctx, &radix, 32); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + in_addr.s_addr = inet_addr("3.3.3.0"); + isc_netaddr_fromin(&netaddr, &in_addr); + NETADDR_TO_PREFIX_T(&netaddr, prefix, 24); + + node = NULL; + result = isc_radix_insert(radix, &node, NULL, &prefix); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + node->data[0] = (void *)1; + isc_refcount_destroy(&prefix.refcount); + + in_addr.s_addr = inet_addr("3.3.0.0"); + isc_netaddr_fromin(&netaddr, &in_addr); + NETADDR_TO_PREFIX_T(&netaddr, prefix, 16); + + node = NULL; + result = isc_radix_insert(radix, &node, NULL, &prefix); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + node->data[0] = (void *)2; + isc_refcount_destroy(&prefix.refcount); + + in_addr.s_addr = inet_addr("3.3.3.3"); + isc_netaddr_fromin(&netaddr, &in_addr); + NETADDR_TO_PREFIX_T(&netaddr, prefix, 22); + + node = NULL; + result = isc_radix_search(radix, &node, &prefix); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + ATF_REQUIRE_EQ(node->data[0], (void *)2); + + isc_refcount_destroy(&prefix.refcount); + + isc_radix_destroy(radix, NULL); + + isc_test_end(); +} + +/* + * Main + */ +ATF_TP_ADD_TCS(tp) { + ATF_TP_ADD_TC(tp, isc_radix_search); + + return (atf_no_error()); +}