aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2012-09-04 11:45:59 -0400
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2012-09-21 15:51:34 -0400
commitb9fed748185a96b7cfe74afac4bd228e8af16f01 (patch)
tree6186be239aee023c11897c2bbde070d32fee0abe /net/netfilter
parent6e27c9b4ee8f348770be5751e6a845ff52a31e19 (diff)
netfilter: ipset: Check and reject crazy /0 input parameters
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>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/ipset/ip_set_bitmap_ip.c10
-rw-r--r--net/netfilter/ipset/ip_set_bitmap_ipmac.c5
-rw-r--r--net/netfilter/ipset/ip_set_hash_ip.c2
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipport.c2
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportip.c2
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportnet.c2
6 files changed, 13 insertions, 10 deletions
diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c
index 7e1b061aeeba..02184b5ef9e1 100644
--- a/net/netfilter/ipset/ip_set_bitmap_ip.c
+++ b/net/netfilter/ipset/ip_set_bitmap_ip.c
@@ -284,7 +284,7 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
284 } else if (tb[IPSET_ATTR_CIDR]) { 284 } else if (tb[IPSET_ATTR_CIDR]) {
285 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 285 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
286 286
287 if (cidr > 32) 287 if (!cidr || cidr > 32)
288 return -IPSET_ERR_INVALID_CIDR; 288 return -IPSET_ERR_INVALID_CIDR;
289 ip_set_mask_from_to(ip, ip_to, cidr); 289 ip_set_mask_from_to(ip, ip_to, cidr);
290 } else 290 } else
@@ -454,7 +454,8 @@ static int
454bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) 454bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
455{ 455{
456 struct bitmap_ip *map; 456 struct bitmap_ip *map;
457 u32 first_ip, last_ip, hosts, elements; 457 u32 first_ip, last_ip, hosts;
458 u64 elements;
458 u8 netmask = 32; 459 u8 netmask = 32;
459 int ret; 460 int ret;
460 461
@@ -497,7 +498,7 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
497 498
498 if (netmask == 32) { 499 if (netmask == 32) {
499 hosts = 1; 500 hosts = 1;
500 elements = last_ip - first_ip + 1; 501 elements = (u64)last_ip - first_ip + 1;
501 } else { 502 } else {
502 u8 mask_bits; 503 u8 mask_bits;
503 u32 mask; 504 u32 mask;
@@ -515,7 +516,8 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
515 if (elements > IPSET_BITMAP_MAX_RANGE + 1) 516 if (elements > IPSET_BITMAP_MAX_RANGE + 1)
516 return -IPSET_ERR_BITMAP_RANGE_SIZE; 517 return -IPSET_ERR_BITMAP_RANGE_SIZE;
517 518
518 pr_debug("hosts %u, elements %u\n", hosts, elements); 519 pr_debug("hosts %u, elements %llu\n",
520 hosts, (unsigned long long)elements);
519 521
520 map = kzalloc(sizeof(*map), GFP_KERNEL); 522 map = kzalloc(sizeof(*map), GFP_KERNEL);
521 if (!map) 523 if (!map)
diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
index d7eaf10edb6d..6819d3cff919 100644
--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
@@ -557,7 +557,8 @@ static int
557bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[], 557bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[],
558 u32 flags) 558 u32 flags)
559{ 559{
560 u32 first_ip, last_ip, elements; 560 u32 first_ip, last_ip;
561 u64 elements;
561 struct bitmap_ipmac *map; 562 struct bitmap_ipmac *map;
562 int ret; 563 int ret;
563 564
@@ -588,7 +589,7 @@ bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[],
588 } else 589 } else
589 return -IPSET_ERR_PROTOCOL; 590 return -IPSET_ERR_PROTOCOL;
590 591
591 elements = last_ip - first_ip + 1; 592 elements = (u64)last_ip - first_ip + 1;
592 593
593 if (elements > IPSET_BITMAP_MAX_RANGE + 1) 594 if (elements > IPSET_BITMAP_MAX_RANGE + 1)
594 return -IPSET_ERR_BITMAP_RANGE_SIZE; 595 return -IPSET_ERR_BITMAP_RANGE_SIZE;
diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
index 42bccd58cbc6..bc8f76edc260 100644
--- a/net/netfilter/ipset/ip_set_hash_ip.c
+++ b/net/netfilter/ipset/ip_set_hash_ip.c
@@ -179,7 +179,7 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
179 } else if (tb[IPSET_ATTR_CIDR]) { 179 } else if (tb[IPSET_ATTR_CIDR]) {
180 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 180 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
181 181
182 if (cidr > 32) 182 if (!cidr || cidr > 32)
183 return -IPSET_ERR_INVALID_CIDR; 183 return -IPSET_ERR_INVALID_CIDR;
184 ip_set_mask_from_to(ip, ip_to, cidr); 184 ip_set_mask_from_to(ip, ip_to, cidr);
185 } else 185 } else
diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
index e0ce0daefac1..6760fd4d7858 100644
--- a/net/netfilter/ipset/ip_set_hash_ipport.c
+++ b/net/netfilter/ipset/ip_set_hash_ipport.c
@@ -217,7 +217,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
217 } else if (tb[IPSET_ATTR_CIDR]) { 217 } else if (tb[IPSET_ATTR_CIDR]) {
218 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 218 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
219 219
220 if (cidr > 32) 220 if (!cidr || cidr > 32)
221 return -IPSET_ERR_INVALID_CIDR; 221 return -IPSET_ERR_INVALID_CIDR;
222 ip_set_mask_from_to(ip, ip_to, cidr); 222 ip_set_mask_from_to(ip, ip_to, cidr);
223 } else 223 } else
diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
index c864bf40e6be..ac09bec274f1 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportip.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
@@ -225,7 +225,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
225 } else if (tb[IPSET_ATTR_CIDR]) { 225 } else if (tb[IPSET_ATTR_CIDR]) {
226 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 226 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
227 227
228 if (cidr > 32) 228 if (!cidr || cidr > 32)
229 return -IPSET_ERR_INVALID_CIDR; 229 return -IPSET_ERR_INVALID_CIDR;
230 ip_set_mask_from_to(ip, ip_to, cidr); 230 ip_set_mask_from_to(ip, ip_to, cidr);
231 } else 231 } else
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
index 2c704bb3cff1..242814e4db4e 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
@@ -290,7 +290,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
290 } else if (tb[IPSET_ATTR_CIDR]) { 290 } else if (tb[IPSET_ATTR_CIDR]) {
291 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 291 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
292 292
293 if (cidr > 32) 293 if (!cidr || cidr > 32)
294 return -IPSET_ERR_INVALID_CIDR; 294 return -IPSET_ERR_INVALID_CIDR;
295 ip_set_mask_from_to(ip, ip_to, cidr); 295 ip_set_mask_from_to(ip, ip_to, cidr);
296 } 296 }