]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
libxtables: properly reject empty hostnames
authorJan Engelhardt <jengelh@medozas.de>
Sat, 9 Jul 2011 14:01:18 +0000 (16:01 +0200)
committerJan Engelhardt <jengelh@medozas.de>
Sat, 9 Jul 2011 14:01:18 +0000 (16:01 +0200)
An empty hostname in the address list of an -s/-d argument, which may
be the result of a typo, is interpreted as 0/0, which, when combined
with -j ACCEPT, leads to an undesired opening of the firewall.

References: http://bugzilla.netfilter.org/show_bug.cgi?id=727
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
iptables/xtables.c

index c4b1c2a8e3d1382fd990e6ec7146ed3759edb860..3b173959cd7bfbfb520b4da3fb5e27b92b063365 100644 (file)
@@ -1299,7 +1299,7 @@ void xtables_ipparse_multiple(const char *name, struct in_addr **addrpp,
                               struct in_addr **maskpp, unsigned int *naddrs)
 {
        struct in_addr *addrp;
-       char buf[256], *p;
+       char buf[256], *p, *next;
        unsigned int len, i, j, n, count = 1;
        const char *loop = name;
 
@@ -1314,23 +1314,17 @@ void xtables_ipparse_multiple(const char *name, struct in_addr **addrpp,
        loop = name;
 
        for (i = 0; i < count; ++i) {
-               if (loop == NULL)
-                       break;
-               if (*loop == ',')
-                       ++loop;
-               if (*loop == '\0')
-                       break;
-               p = strchr(loop, ',');
-               if (p != NULL)
-                       len = p - loop;
+               next = strchr(loop, ',');
+               if (next != NULL)
+                       len = next - loop;
                else
                        len = strlen(loop);
-               if (len == 0 || sizeof(buf) - 1 < len)
-                       break;
+               if (len > sizeof(buf) - 1)
+                       xt_params->exit_err(PARAMETER_PROBLEM,
+                               "Hostname too long");
 
                strncpy(buf, loop, len);
                buf[len] = '\0';
-               loop += len;
                if ((p = strrchr(buf, '/')) != NULL) {
                        *p = '\0';
                        addrp = parse_ipmask(p + 1);
@@ -1368,6 +1362,9 @@ void xtables_ipparse_multiple(const char *name, struct in_addr **addrpp,
                }
                /* free what ipparse_hostnetwork had allocated: */
                free(addrp);
+               if (next == NULL)
+                       break;
+               loop = next + 1;
        }
        *naddrs = count;
        for (i = 0; i < count; ++i)
@@ -1616,7 +1613,7 @@ xtables_ip6parse_multiple(const char *name, struct in6_addr **addrpp,
 {
        static const struct in6_addr zero_addr;
        struct in6_addr *addrp;
-       char buf[256], *p;
+       char buf[256], *p, *next;
        unsigned int len, i, j, n, count = 1;
        const char *loop = name;
 
@@ -1631,23 +1628,17 @@ xtables_ip6parse_multiple(const char *name, struct in6_addr **addrpp,
        loop = name;
 
        for (i = 0; i < count /*NB: count can grow*/; ++i) {
-               if (loop == NULL)
-                       break;
-               if (*loop == ',')
-                       ++loop;
-               if (*loop == '\0')
-                       break;
-               p = strchr(loop, ',');
-               if (p != NULL)
-                       len = p - loop;
+               next = strchr(loop, ',');
+               if (next != NULL)
+                       len = next - loop;
                else
                        len = strlen(loop);
-               if (len == 0 || sizeof(buf) - 1 < len)
-                       break;
+               if (len > sizeof(buf) - 1)
+                       xt_params->exit_err(PARAMETER_PROBLEM,
+                               "Hostname too long");
 
                strncpy(buf, loop, len);
                buf[len] = '\0';
-               loop += len;
                if ((p = strrchr(buf, '/')) != NULL) {
                        *p = '\0';
                        addrp = parse_ip6mask(p + 1);
@@ -1681,6 +1672,9 @@ xtables_ip6parse_multiple(const char *name, struct in6_addr **addrpp,
                }
                /* free what ip6parse_hostnetwork had allocated: */
                free(addrp);
+               if (next == NULL)
+                       break;
+               loop = next + 1;
        }
        *naddrs = count;
        for (i = 0; i < count; ++i)