]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Detect partial prefixes / incomplete IPv4 address in acls.
authorMark Andrews <marka@isc.org>
Mon, 15 Jul 2019 00:25:36 +0000 (10:25 +1000)
committerMark Andrews <marka@isc.org>
Sun, 13 Oct 2019 14:31:44 +0000 (01:31 +1100)
(cherry picked from commit fb87e669fb3cb7148fc5ff4226b20837971c3e66)

CHANGES
bin/tests/system/checkconf/bad-ipv4-prefix-dotted1.conf [new file with mode: 0644]
bin/tests/system/checkconf/bad-ipv4-prefix-dotted2.conf [new file with mode: 0644]
bin/tests/system/checkconf/bad-ipv4-prefix2.conf [new file with mode: 0644]
lib/isc/include/isc/result.h
lib/isc/result.c
lib/isccfg/parser.c

diff --git a/CHANGES b/CHANGES
index 604f731cd2c73e80393ac7d6d4fe9138b39487c5..f8573bf25467eab8f815bb141a88d4ac4eeb5f1c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+5301.  [bug]           Detect partial prefixes / incomplete IPv4 address in
+                       acls. [GL #1143]
+
 5297.  [bug]           Check whether a previous QNAME minimization fetch
                        is still running before starting a new one; return
                        SERVFAIL and log an error if so. [GL #1191]
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 (file)
index 0000000..e07cc83
--- /dev/null
@@ -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 (file)
index 0000000..ae098be
--- /dev/null
@@ -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 (file)
index 0000000..4d7738c
--- /dev/null
@@ -0,0 +1,3 @@
+acl myacl {
+       127; /* Non-dotted quad IPv4 address (0.0.0.127) / prefix without length. */
+};
index 36792fa0dcbd3b7f8c9535d31f2bf081e765e6d8..96f5f2bdff77db663e9fe8b5733842cd012120e0 100644 (file)
 #define ISC_R_CRYPTOFAILURE            65      /*%< cryptography library failure */
 #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                         68
+#define ISC_R_NRESULTS                         70
 
 ISC_LANG_BEGINDECLS
 
index 7eb4284022a0a820427c68efa810a898ad1b1e7f..2fe9b5cdec275b5a9d135610c646fafb50991d63 100644 (file)
@@ -101,6 +101,8 @@ static const char *description[ISC_R_NRESULTS] = {
        "crypto failure",                       /*%< 65 */
        "disc quota",                           /*%< 66 */
        "disc full",                            /*%< 67 */
+       "default",                              /*%< 68 */
+       "IPv4 prefix",                          /*%< 69 */
 };
 
 static const char *identifier[ISC_R_NRESULTS] = {
@@ -172,6 +174,8 @@ static const char *identifier[ISC_R_NRESULTS] = {
        "ISC_R_CRYPTOFAILURE",
        "ISC_R_DISCQUOTA",
        "ISC_R_DISCFULL",
+       "ISC_R_DEFAULT",
+       "ISC_R_IPV4PREFIX",
 };
 
 #define ISC_RESULT_RESULTSET                   2
index edc6f5bffe468a705b8f55f5f98a498e200172ec..4bbf392c1979fd9fc9c4d3bac19473e72dd47f26 100644 (file)
@@ -2604,7 +2604,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);
                                }
                        }
                }
@@ -2680,7 +2680,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
@@ -2844,14 +2844,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;
@@ -2863,6 +2867,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 == '/') {
@@ -2870,16 +2875,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));