iptables: fix regression with unintended free in need_protomatch
[project/firewall3.git] / options.c
index c763d9e8078207bf50841e9e7b28f85653686e21..2f419a3a9b45b63e88f1a739050fe3ba82841967 100644 (file)
--- a/options.c
+++ b/options.c
@@ -146,6 +146,7 @@ static const struct { const char *name; uint8_t dscp; } dscp_classes[] = {
        { "CS6",  0x30 },
        { "CS7",  0x38 },
        { "BE",   0x00 },
+       { "LE",   0x01 },
        { "AF11", 0x0a },
        { "AF12", 0x0c },
        { "AF13", 0x0e },
@@ -568,7 +569,7 @@ fw3_parse_icmptype(void *ptr, const char *val, bool is_list)
                }
 
                icmp.type6     = icmp.type;
-               icmp.code6_min = icmp.code_max;
+               icmp.code6_min = icmp.code_min;
                icmp.code6_max = icmp.code_max;
 
                v4 = true;
@@ -939,7 +940,7 @@ fw3_parse_setmatch(void *ptr, const char *val, bool is_list)
                return false;
        }
 
-       strncpy(m->name, p, sizeof(m->name) - 1);
+       snprintf(m->name, sizeof(m->name), "%s", p);
 
        for (i = 0, p = strtok(NULL, " \t,");
             i < 3 && p != NULL;
@@ -987,7 +988,7 @@ fw3_parse_cthelper(void *ptr, const char *val, bool is_list)
        if (*val)
        {
                m.set = true;
-               strncpy(m.name, val, sizeof(m.name) - 1);
+               snprintf(m.name, sizeof(m.name), "%s", val);
                put_value(ptr, &m, sizeof(m), is_list);
                return true;
        }
@@ -1170,6 +1171,9 @@ fw3_parse_blob_options(void *s, const struct fw3_option *opts,
                                                if (blobmsg_type(e) == BLOBMSG_TYPE_INT32) {
                                                        snprintf(buf, sizeof(buf), "%d", blobmsg_get_u32(e));
                                                        v = buf;
+                                               } else if (blobmsg_type(o) == BLOBMSG_TYPE_BOOL) {
+                                                       snprintf(buf, sizeof(buf), "%d", blobmsg_get_bool(o));
+                                                       v = buf;
                                                } else {
                                                        v = blobmsg_get_string(e);
                                                }
@@ -1189,6 +1193,9 @@ fw3_parse_blob_options(void *s, const struct fw3_option *opts,
                                if (blobmsg_type(o) == BLOBMSG_TYPE_INT32) {
                                        snprintf(buf, sizeof(buf), "%d", blobmsg_get_u32(o));
                                        v = buf;
+                               } else if (blobmsg_type(o) == BLOBMSG_TYPE_BOOL) {
+                                       snprintf(buf, sizeof(buf), "%d", blobmsg_get_bool(o));
+                                       v = buf;
                                } else {
                                        v = blobmsg_get_string(o);
                                }
@@ -1239,35 +1246,46 @@ fw3_address_to_string(struct fw3_address *address, bool allow_invert, bool as_ci
 {
        char *p, ip[INET6_ADDRSTRLEN];
        static char buf[INET6_ADDRSTRLEN * 2 + 2];
+       size_t rem = sizeof(buf);
+       int len;
 
        p = buf;
 
-       if (address->invert && allow_invert)
-               p += sprintf(p, "!");
+       if (address->invert && allow_invert) {
+               *p++ = '!';
+               *p = 0;
+               rem--;
+       }
 
        inet_ntop(address->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
                  &address->address.v4, ip, sizeof(ip));
 
-       p += sprintf(p, "%s", ip);
+       len = snprintf(p, rem, "%s", ip);
+
+       if (len < 0 || len >= rem)
+               return buf;
+
+       rem -= len;
+       p += len;
 
        if (address->range)
        {
                inet_ntop(address->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
                          &address->mask.v4, ip, sizeof(ip));
 
-               p += sprintf(p, "-%s", ip);
+               snprintf(p, rem, "-%s", ip);
        }
        else if (!as_cidr)
        {
                inet_ntop(address->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
                          &address->mask.v4, ip, sizeof(ip));
 
-               p += sprintf(p, "/%s", ip);
+               snprintf(p, rem, "/%s", ip);
        }
        else
        {
-               p += sprintf(p, "/%u", fw3_netmask2bitlen(address->family,
-                                                         &address->mask.v6));
+               snprintf(p, rem, "/%u",
+                        fw3_netmask2bitlen(address->family, &address->mask.v6));
        }
 
        return buf;