netfilter: ipset: Check and reject crazy /0 input parameters
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Tue, 4 Sep 2012 15:45:59 +0000 (17:45 +0200)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Fri, 21 Sep 2012 19:51:34 +0000 (21:51 +0200)
bitmap:ip and bitmap:ip,mac type did not reject such a crazy range
when created and using such a set results in a kernel crash.
The hash types just silently ignored such parameters.

Reject invalid /0 input parameters explicitely.

Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
net/netfilter/ipset/ip_set_bitmap_ip.c
net/netfilter/ipset/ip_set_bitmap_ipmac.c
net/netfilter/ipset/ip_set_hash_ip.c
net/netfilter/ipset/ip_set_hash_ipport.c
net/netfilter/ipset/ip_set_hash_ipportip.c
net/netfilter/ipset/ip_set_hash_ipportnet.c

index 7e1b061aeeba4c14cb45785b2975b353ab18a314..02184b5ef9e13b1c1f146ba9a863b1cc037f3959 100644 (file)
@@ -284,7 +284,7 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
        } else if (tb[IPSET_ATTR_CIDR]) {
                u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
 
-               if (cidr > 32)
+               if (!cidr || cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
                ip_set_mask_from_to(ip, ip_to, cidr);
        } else
@@ -454,7 +454,8 @@ static int
 bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
 {
        struct bitmap_ip *map;
-       u32 first_ip, last_ip, hosts, elements;
+       u32 first_ip, last_ip, hosts;
+       u64 elements;
        u8 netmask = 32;
        int ret;
 
@@ -497,7 +498,7 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
 
        if (netmask == 32) {
                hosts = 1;
-               elements = last_ip - first_ip + 1;
+               elements = (u64)last_ip - first_ip + 1;
        } else {
                u8 mask_bits;
                u32 mask;
@@ -515,7 +516,8 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
        if (elements > IPSET_BITMAP_MAX_RANGE + 1)
                return -IPSET_ERR_BITMAP_RANGE_SIZE;
 
-       pr_debug("hosts %u, elements %u\n", hosts, elements);
+       pr_debug("hosts %u, elements %llu\n",
+                hosts, (unsigned long long)elements);
 
        map = kzalloc(sizeof(*map), GFP_KERNEL);
        if (!map)
index d7eaf10edb6d311f26a0b1e2bceac856c1085ae8..6819d3cff9196c16b84a0eb5f3db96334c25e347 100644 (file)
@@ -557,7 +557,8 @@ static int
 bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[],
                    u32 flags)
 {
-       u32 first_ip, last_ip, elements;
+       u32 first_ip, last_ip;
+       u64 elements;
        struct bitmap_ipmac *map;
        int ret;
 
@@ -588,7 +589,7 @@ bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[],
        } else
                return -IPSET_ERR_PROTOCOL;
 
-       elements = last_ip - first_ip + 1;
+       elements = (u64)last_ip - first_ip + 1;
 
        if (elements > IPSET_BITMAP_MAX_RANGE + 1)
                return -IPSET_ERR_BITMAP_RANGE_SIZE;
index 42bccd58cbc6df6acf05c2e7dd8f5457ecb2ef56..bc8f76edc260d1df0ea41af25f79218cd83dd6a7 100644 (file)
@@ -179,7 +179,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
        } else if (tb[IPSET_ATTR_CIDR]) {
                u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
 
-               if (cidr > 32)
+               if (!cidr || cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
                ip_set_mask_from_to(ip, ip_to, cidr);
        } else
index e0ce0daefac1397cafe85df0e745d138ee12e758..6760fd4d7858b5f0277c6f6e54ddfd76a53333e1 100644 (file)
@@ -217,7 +217,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
        } else if (tb[IPSET_ATTR_CIDR]) {
                u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
 
-               if (cidr > 32)
+               if (!cidr || cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
                ip_set_mask_from_to(ip, ip_to, cidr);
        } else
index c864bf40e6beb8ad5d61da4ffb8de88ae9f3257c..ac09bec274f1970f6a9b94e87e9b4d457cded599 100644 (file)
@@ -225,7 +225,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
        } else if (tb[IPSET_ATTR_CIDR]) {
                u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
 
-               if (cidr > 32)
+               if (!cidr || cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
                ip_set_mask_from_to(ip, ip_to, cidr);
        } else
index 2c704bb3cff154c0f3ab49ffb7d5f3b71fb10fe3..242814e4db4eb9c10e4c20fba74e131a96b520d1 100644 (file)
@@ -290,7 +290,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
        } else if (tb[IPSET_ATTR_CIDR]) {
                u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
 
-               if (cidr > 32)
+               if (!cidr || cidr > 32)
                        return -IPSET_ERR_INVALID_CIDR;
                ip_set_mask_from_to(ip, ip_to, cidr);
        }