From: Mark Andrews Date: Mon, 15 Jul 2019 00:25:36 +0000 (+1000) Subject: Detect partial prefixes / incomplete IPv4 address in acls. X-Git-Tag: v9.15.6~62^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fb87e669fb3cb7148fc5ff4226b20837971c3e66;p=thirdparty%2Fbind9.git Detect partial prefixes / incomplete IPv4 address in acls. --- diff --git a/CHANGES b/CHANGES index eb6286b022d..d34cc8b978b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +5301. [bug] Detect partial prefixes / incomplete IPv4 address in + acls. [GL #1143] + 5300. [bug] dig/mdig/delv: Add a colon after EDNS option names, even when the option is empty, to improve readability and allow correct parsing of YAML diff --git a/bin/tests/system/checkconf/bad-ipv4-prefix-dotted1.conf b/bin/tests/system/checkconf/bad-ipv4-prefix-dotted1.conf new file mode 100644 index 00000000000..e07cc839c9e --- /dev/null +++ b/bin/tests/system/checkconf/bad-ipv4-prefix-dotted1.conf @@ -0,0 +1,3 @@ +acl myacl { + 127.1; /* Incomplete dotted IPv4 address / prefix */ +}; diff --git a/bin/tests/system/checkconf/bad-ipv4-prefix-dotted2.conf b/bin/tests/system/checkconf/bad-ipv4-prefix-dotted2.conf new file mode 100644 index 00000000000..ae098be5d5c --- /dev/null +++ b/bin/tests/system/checkconf/bad-ipv4-prefix-dotted2.conf @@ -0,0 +1,3 @@ +acl myacl { + 127.1/8; /* No-zero bits */ +}; diff --git a/bin/tests/system/checkconf/bad-ipv4-prefix2.conf b/bin/tests/system/checkconf/bad-ipv4-prefix2.conf new file mode 100644 index 00000000000..4d7738c9553 --- /dev/null +++ b/bin/tests/system/checkconf/bad-ipv4-prefix2.conf @@ -0,0 +1,3 @@ +acl myacl { + 127; /* Non-dotted quad IPv4 address (0.0.0.127) / prefix without length. */ +}; diff --git a/lib/isc/include/isc/result.h b/lib/isc/include/isc/result.h index 634a343b5da..96f5f2bdff7 100644 --- a/lib/isc/include/isc/result.h +++ b/lib/isc/include/isc/result.h @@ -88,9 +88,10 @@ #define ISC_R_DISCQUOTA 66 /*%< disc quota */ #define ISC_R_DISCFULL 67 /*%< disc full */ #define ISC_R_DEFAULT 68 /*%< default */ +#define ISC_R_IPV4PREFIX 69 /*%< IPv4 prefix */ /*% Not a result code: the number of results. */ -#define ISC_R_NRESULTS 69 +#define ISC_R_NRESULTS 70 ISC_LANG_BEGINDECLS diff --git a/lib/isc/result.c b/lib/isc/result.c index 3cfaa86c725..ff3ca024138 100644 --- a/lib/isc/result.c +++ b/lib/isc/result.c @@ -100,6 +100,7 @@ static const char *description[ISC_R_NRESULTS] = { "disc quota", /*%< 66 */ "disc full", /*%< 67 */ "default", /*%< 68 */ + "IPv4 prefix", /*%< 69 */ }; static const char *identifier[ISC_R_NRESULTS] = { @@ -172,6 +173,7 @@ static const char *identifier[ISC_R_NRESULTS] = { "ISC_R_DISCQUOTA", "ISC_R_DISCFULL", "ISC_R_DEFAULT", + "ISC_R_IPV4PREFIX", }; #define ISC_RESULT_RESULTSET 2 diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index c744e296f46..0c7987b8810 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -2618,7 +2618,7 @@ token_addr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na) { strlcat(buf, ".0", sizeof(buf)); if (inet_pton(AF_INET, buf, &in4a) == 1) { isc_netaddr_fromin(na, &in4a); - return (ISC_R_SUCCESS); + return (ISC_R_IPV4PREFIX); } } } @@ -2694,7 +2694,7 @@ cfg_lookingat_netaddr(cfg_parser_t *pctx, unsigned int flags) { REQUIRE(pctx != NULL); result = token_addr(pctx, flags, &na_dummy); - return (result == ISC_R_SUCCESS); + return (result == ISC_R_SUCCESS || result == ISC_R_IPV4PREFIX); } isc_result_t @@ -2858,14 +2858,18 @@ cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type, isc_result_t result; isc_netaddr_t netaddr; unsigned int addrlen = 0, prefixlen; + bool expectprefix; REQUIRE(pctx != NULL); REQUIRE(ret != NULL && *ret == NULL); UNUSED(type); - CHECK(cfg_parse_rawaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V4PREFIXOK | - CFG_ADDR_V6OK, &netaddr)); + result = cfg_parse_rawaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V4PREFIXOK | + CFG_ADDR_V6OK, &netaddr); + if (result != ISC_R_SUCCESS && result != ISC_R_IPV4PREFIX) { + CHECK(result); + } switch (netaddr.family) { case AF_INET: addrlen = 32; @@ -2877,6 +2881,7 @@ cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type, INSIST(0); ISC_UNREACHABLE(); } + expectprefix = (result == ISC_R_IPV4PREFIX); CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_special && pctx->token.value.as_char == '/') { @@ -2884,16 +2889,30 @@ cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type, CHECK(cfg_gettoken(pctx, ISC_LEXOPT_NUMBER)); if (pctx->token.type != isc_tokentype_number) { cfg_parser_error(pctx, CFG_LOG_NEAR, - "expected prefix length"); + "expected prefix length"); return (ISC_R_UNEXPECTEDTOKEN); } prefixlen = pctx->token.value.as_ulong; if (prefixlen > addrlen) { cfg_parser_error(pctx, CFG_LOG_NOPREP, - "invalid prefix length"); + "invalid prefix length"); return (ISC_R_RANGE); } + result = isc_netaddr_prefixok(&netaddr, prefixlen); + if (result != ISC_R_SUCCESS) { + char buf[ISC_NETADDR_FORMATSIZE + 1]; + isc_netaddr_format(&netaddr, buf, sizeof(buf)); + cfg_parser_error(pctx, CFG_LOG_NOPREP, + "'%s/%u': address/prefix length " + "mismatch", buf, prefixlen); + return (ISC_R_FAILURE); + } } else { + if (expectprefix) { + cfg_parser_error(pctx, CFG_LOG_NEAR, + "incomplete IPv4 address or prefix"); + return (ISC_R_FAILURE); + } prefixlen = addrlen; } CHECK(cfg_create_obj(pctx, &cfg_type_netprefix, &obj));