diff options
author | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2018-01-12 10:36:25 +0100 |
---|---|---|
committer | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2018-01-12 10:36:25 +0100 |
commit | 82403f9c229f093e973888e778646b4206a1469f (patch) | |
tree | 6d8fb3cdfdc9aae1a0d8c0e953ebac575ae2d22a /kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c | |
parent | b1b217c885e1ad36d0b0a5a83fc1900e3a6d71ed (diff) |
Fix wraparound bug introduced in commit 48596a8ddc46
The patch "netfilter: ipset: Fix adding an IPv4 range containing
more than 2^31 addresses" introduced a wraparound bug, which could
lead to memory exhaustion when adding an x.x.x.x-255.255.255.255
range to any hash:*net* types.
Fixes Netfilter's bugzilla id #1212, reported by Thomas Schwark.
Diffstat (limited to 'kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c')
-rw-r--r-- | kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c b/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c index 0f164e9..88b83d6 100644 --- a/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c @@ -168,7 +168,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], struct hash_ipportnet4_elem e = { .cidr = HOST_MASK - 1 }; struct ip_set_ext ext = IP_SET_INIT_UEXT(set); u32 ip = 0, ip_to = 0, p = 0, port, port_to; - u32 ip2_from = 0, ip2_to = 0, ip2_last, ip2; + u32 ip2_from = 0, ip2_to = 0, ip2; bool with_ports = false; u8 cidr; int ret; @@ -269,22 +269,21 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], ip_set_mask_from_to(ip2_from, ip2_to, e.cidr + 1); } - if (retried) + if (retried) { ip = ntohl(h->next.ip); + p = ntohs(h->next.port); + ip2 = ntohl(h->next.ip2); + } else { + p = port; + ip2 = ip2_from; + } for (; ip <= ip_to; ip++) { e.ip = htonl(ip); - p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) - : port; for (; p <= port_to; p++) { e.port = htons(p); - ip2 = retried && - ip == ntohl(h->next.ip) && - p == ntohs(h->next.port) - ? ntohl(h->next.ip2) : ip2_from; - while (ip2 <= ip2_to) { + do { e.ip2 = htonl(ip2); - ip2_last = ip_set_range_to_cidr(ip2, ip2_to, - &cidr); + ip2 = ip_set_range_to_cidr(ip2, ip2_to, &cidr); e.cidr = cidr - 1; ret = adtfn(set, &e, &ext, &ext, flags); @@ -292,9 +291,10 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], return ret; ret = 0; - ip2 = ip2_last + 1; - } + } while (ip2++ < ip2_to); + ip2 = ip2_from; } + p = port; } return ret; } |