From 2b4781835cf0d39834d9742f1b13e2fd150cdea1 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Fri, 7 Mar 2014 11:36:20 -0800 Subject: [PATCH] [v9_9] warn when wrong address family used in listen-on/-v6 3778. [bug] Log a warning when the wrong address family is used in "listen-on" or "listen-on-v6". [RT #17848] (cherry picked from commit 78f79084fcfc40f1237c99e2d4325b24b750d012) --- CHANGES | 3 +++ bin/named/server.c | 30 +++++++++++++++-------------- doc/arm/Bv9ARM-book.xml | 28 +++++++++++++++------------ lib/isccfg/aclconf.c | 29 ++++++++++++++++++++++------ lib/isccfg/include/isccfg/aclconf.h | 20 +++++++++++++------ lib/isccfg/win32/libisccfg.def | 1 + 6 files changed, 73 insertions(+), 38 deletions(-) diff --git a/CHANGES b/CHANGES index 1109e15966..8adcdac712 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3778. [bug] Log a warning when the wrong address family is + used in "listen-on" or "listen-on-v6". [RT #17848] + 3775. [bug] dlz_dlopen driver could return the wrong error code on API version mismatch, leading to a segfault. [RT #35495] diff --git a/bin/named/server.c b/bin/named/server.c index a79db8d3d4..dad4a8f9fe 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -357,12 +357,12 @@ ns_server_reload(isc_task_t *task, isc_event_t *event); static isc_result_t ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenelt_t **target); + cfg_aclconfctx_t *actx, isc_mem_t *mctx, + isc_uint16_t family, ns_listenelt_t **target); static isc_result_t ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenlist_t **target); + cfg_aclconfctx_t *actx, isc_mem_t *mctx, + isc_uint16_t family, ns_listenlist_t **target); static isc_result_t configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin, @@ -5231,7 +5231,8 @@ load_configuration(const char *filename, ns_server_t *server, /* check return code? */ (void)ns_listenlist_fromconfig(clistenon, config, ns_g_aclconfctx, - ns_g_mctx, &listenon); + ns_g_mctx, AF_INET, + &listenon); } else if (!ns_g_lwresdonly) { /* * Not specified, use default. @@ -5258,7 +5259,8 @@ load_configuration(const char *filename, ns_server_t *server, /* check return code? */ (void)ns_listenlist_fromconfig(clistenon, config, ns_g_aclconfctx, - ns_g_mctx, &listenon); + ns_g_mctx, AF_INET6, + &listenon); } else if (!ns_g_lwresdonly) { isc_boolean_t enable; /* @@ -6819,8 +6821,8 @@ ns_server_togglequerylog(ns_server_t *server, char *args) { static isc_result_t ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenlist_t **target) + cfg_aclconfctx_t *actx, isc_mem_t *mctx, + isc_uint16_t family, ns_listenlist_t **target) { isc_result_t result; const cfg_listelt_t *element; @@ -6839,7 +6841,7 @@ ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, ns_listenelt_t *delt = NULL; const cfg_obj_t *listener = cfg_listelt_value(element); result = ns_listenelt_fromconfig(listener, config, actx, - mctx, &delt); + mctx, family, &delt); if (result != ISC_R_SUCCESS) goto cleanup; ISC_LIST_APPEND(dlist->elts, delt, link); @@ -6858,8 +6860,8 @@ ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, */ static isc_result_t ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenelt_t **target) + cfg_aclconfctx_t *actx, isc_mem_t *mctx, + isc_uint16_t family, ns_listenelt_t **target) { isc_result_t result; const cfg_obj_t *portobj; @@ -6890,9 +6892,9 @@ ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, if (result != ISC_R_SUCCESS) return (result); - result = cfg_acl_fromconfig(cfg_tuple_get(listener, "acl"), - config, ns_g_lctx, actx, mctx, 0, - &delt->acl); + result = cfg_acl_fromconfig2(cfg_tuple_get(listener, "acl"), + config, ns_g_lctx, actx, mctx, 0, + family, &delt->acl); if (result != ISC_R_SUCCESS) { ns_listenelt_destroy(delt); return (result); diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index c8e2699386..d615886c5b 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -4598,8 +4598,8 @@ badresp:1,adberr:0,findfail:0,valfail:0] The listen-on statement specifies a list of - addresses (and ports) that this instance of a lightweight resolver - daemon + IPv4 addresses (and ports) that this instance of a lightweight + resolver daemon should accept requests on. If no port is specified, port 921 is used. If this statement is omitted, requests will be accepted on @@ -7142,11 +7142,13 @@ options { Interfaces - The interfaces and ports that the server will answer queries - from may be specified using the listen-on option. listen-on takes - an optional port and an address_match_list. - The server will listen on all interfaces allowed by the address - match list. If a port is not specified, port 53 will be used. + The interfaces and ports that the server will answer queries + from may be specified using the listen-on option. listen-on takes + an optional port and an address_match_list + of IPv4 addresses. (IPv6 addresses are ignored, with a + logged warning.) + The server will listen on all interfaces allowed by the address + match list. If a port is not specified, port 53 will be used. Multiple listen-on statements are @@ -7191,11 +7193,13 @@ listen-on port 1234 { !1.2.3.4; 1.2/16; }; - A list of particular IPv6 addresses can also be specified, in - which case - the server listens on a separate socket for each specified - address, - regardless of whether the desired API is supported by the system. + A list of particular IPv6 addresses can also be specified, in + which case + the server listens on a separate socket for each specified + address, + regardless of whether the desired API is supported by the system. + IPv4 addresses specified in listen-on-v6 + will be ignored, with a logged warning. diff --git a/lib/isccfg/aclconf.c b/lib/isccfg/aclconf.c index af5659909e..ec1ce1dd4b 100644 --- a/lib/isccfg/aclconf.c +++ b/lib/isccfg/aclconf.c @@ -263,13 +263,20 @@ count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx, } isc_result_t -cfg_acl_fromconfig(const cfg_obj_t *caml, - const cfg_obj_t *cctx, - isc_log_t *lctx, - cfg_aclconfctx_t *ctx, - isc_mem_t *mctx, - unsigned int nest_level, +cfg_acl_fromconfig(const cfg_obj_t *caml, const cfg_obj_t *cctx, + isc_log_t *lctx, cfg_aclconfctx_t *ctx, + isc_mem_t *mctx, unsigned int nest_level, dns_acl_t **target) +{ + return (cfg_acl_fromconfig2(caml, cctx, lctx, ctx, mctx, + nest_level, 0, target)); +} + +isc_result_t +cfg_acl_fromconfig2(const cfg_obj_t *caml, const cfg_obj_t *cctx, + isc_log_t *lctx, cfg_aclconfctx_t *ctx, + isc_mem_t *mctx, unsigned int nest_level, + isc_uint16_t family, dns_acl_t **target) { isc_result_t result; dns_acl_t *dacl = NULL, *inneracl = NULL; @@ -349,6 +356,16 @@ cfg_acl_fromconfig(const cfg_obj_t *caml, unsigned int bitlen; cfg_obj_asnetprefix(ce, &addr, &bitlen); + if (family != 0 && family != addr.family) { + char buf[ISC_NETADDR_FORMATSIZE + 1]; + isc_netaddr_format(&addr, buf, sizeof(buf)); + cfg_obj_log(ce, lctx, ISC_LOG_WARNING, + "'%s': incorrect address family; " + "ignoring", buf); + if (nest_level != 0) + dns_acl_detach(&de->nestedacl); + continue; + } /* * If nesting ACLs (nest_level != 0), we negate diff --git a/lib/isccfg/include/isccfg/aclconf.h b/lib/isccfg/include/isccfg/aclconf.h index 38ab9f696f..a16bd40974 100644 --- a/lib/isccfg/include/isccfg/aclconf.h +++ b/lib/isccfg/include/isccfg/aclconf.h @@ -58,13 +58,16 @@ cfg_aclconfctx_attach(cfg_aclconfctx_t *src, cfg_aclconfctx_t **dest); */ isc_result_t -cfg_acl_fromconfig(const cfg_obj_t *caml, - const cfg_obj_t *cctx, - isc_log_t *lctx, - cfg_aclconfctx_t *ctx, - isc_mem_t *mctx, - unsigned int nest_level, +cfg_acl_fromconfig(const cfg_obj_t *caml, const cfg_obj_t *cctx, + isc_log_t *lctx, cfg_aclconfctx_t *ctx, + isc_mem_t *mctx, unsigned int nest_level, dns_acl_t **target); + +isc_result_t +cfg_acl_fromconfig2(const cfg_obj_t *caml, const cfg_obj_t *cctx, + isc_log_t *lctx, cfg_aclconfctx_t *ctx, + isc_mem_t *mctx, unsigned int nest_level, + isc_uint16_t family, dns_acl_t **target); /* * Construct a new dns_acl_t from configuration data in 'caml' and * 'cctx'. Memory is allocated through 'mctx'. @@ -75,6 +78,11 @@ cfg_acl_fromconfig(const cfg_obj_t *caml, * nested dns_acl_t object when the referring objects were created * passing the same ACL configuration context 'ctx'. * + * cfg_acl_fromconfig() is a backward-compatible version of + * cfg_acl_fromconfig2(), which allows an address family to be + * specified. If 'family' is not zero, then only addresses/prefixes + * of a matching family (AF_INET or AF_INET6) may be configured. + * * On success, attach '*target' to the new dns_acl_t object. */ diff --git a/lib/isccfg/win32/libisccfg.def b/lib/isccfg/win32/libisccfg.def index 95cdcc782b..00567a9c35 100644 --- a/lib/isccfg/win32/libisccfg.def +++ b/lib/isccfg/win32/libisccfg.def @@ -4,6 +4,7 @@ LIBRARY libisccfg EXPORTS cfg_acl_fromconfig +cfg_acl_fromconfig2 cfg_aclconfctx_attach cfg_aclconfctx_create cfg_aclconfctx_detach