netfilter: ipset: Fix adding an IPv4 range containing more than 2^31 addresses

Wrong comparison prevented the hash types to add a range with more than
2^31 addresses but reported as a success.

Fixes Netfilter's bugzilla id #1005, reported by Oleg Serditov and
Oliver Ford.

Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Jozsef Kadlecsik 2017-09-23 23:37:40 +02:00 committed by Pablo Neira Ayuso
parent 89fcbb564f
commit 48596a8ddc
10 changed files with 24 additions and 22 deletions

View File

@ -123,13 +123,12 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
return ret; return ret;
ip &= ip_set_hostmask(h->netmask); ip &= ip_set_hostmask(h->netmask);
if (adt == IPSET_TEST) {
e.ip = htonl(ip); e.ip = htonl(ip);
if (e.ip == 0) if (e.ip == 0)
return -IPSET_ERR_HASH_ELEM; return -IPSET_ERR_HASH_ELEM;
if (adt == IPSET_TEST)
return adtfn(set, &e, &ext, &ext, flags); return adtfn(set, &e, &ext, &ext, flags);
}
ip_to = ip; ip_to = ip;
if (tb[IPSET_ATTR_IP_TO]) { if (tb[IPSET_ATTR_IP_TO]) {
@ -148,17 +147,20 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1); hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1);
if (retried) if (retried) {
ip = ntohl(h->next.ip); ip = ntohl(h->next.ip);
for (; !before(ip_to, ip); ip += hosts) {
e.ip = htonl(ip); e.ip = htonl(ip);
if (e.ip == 0) }
return -IPSET_ERR_HASH_ELEM; for (; ip <= ip_to;) {
ret = adtfn(set, &e, &ext, &ext, flags); ret = adtfn(set, &e, &ext, &ext, flags);
if (ret && !ip_set_eexist(ret, flags)) if (ret && !ip_set_eexist(ret, flags))
return ret; return ret;
ip += hosts;
e.ip = htonl(ip);
if (e.ip == 0)
return 0;
ret = 0; ret = 0;
} }
return ret; return ret;

View File

@ -149,7 +149,7 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
if (retried) if (retried)
ip = ntohl(h->next.ip); ip = ntohl(h->next.ip);
for (; !before(ip_to, ip); ip++) { for (; ip <= ip_to; ip++) {
e.ip = htonl(ip); e.ip = htonl(ip);
ret = adtfn(set, &e, &ext, &ext, flags); ret = adtfn(set, &e, &ext, &ext, flags);

View File

@ -178,7 +178,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
if (retried) if (retried)
ip = ntohl(h->next.ip); ip = ntohl(h->next.ip);
for (; !before(ip_to, ip); ip++) { for (; ip <= ip_to; ip++) {
p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
: port; : port;
for (; p <= port_to; p++) { for (; p <= port_to; p++) {

View File

@ -185,7 +185,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
if (retried) if (retried)
ip = ntohl(h->next.ip); ip = ntohl(h->next.ip);
for (; !before(ip_to, ip); ip++) { for (; ip <= ip_to; ip++) {
p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
: port; : port;
for (; p <= port_to; p++) { for (; p <= port_to; p++) {

View File

@ -271,7 +271,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
if (retried) if (retried)
ip = ntohl(h->next.ip); ip = ntohl(h->next.ip);
for (; !before(ip_to, ip); ip++) { for (; ip <= ip_to; ip++) {
e.ip = htonl(ip); e.ip = htonl(ip);
p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
: port; : port;
@ -281,7 +281,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
ip == ntohl(h->next.ip) && ip == ntohl(h->next.ip) &&
p == ntohs(h->next.port) p == ntohs(h->next.port)
? ntohl(h->next.ip2) : ip2_from; ? ntohl(h->next.ip2) : ip2_from;
while (!after(ip2, ip2_to)) { while (ip2 <= ip2_to) {
e.ip2 = htonl(ip2); e.ip2 = htonl(ip2);
ip2_last = ip_set_range_to_cidr(ip2, ip2_to, ip2_last = ip_set_range_to_cidr(ip2, ip2_to,
&cidr); &cidr);

View File

@ -193,7 +193,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
} }
if (retried) if (retried)
ip = ntohl(h->next.ip); ip = ntohl(h->next.ip);
while (!after(ip, ip_to)) { while (ip <= ip_to) {
e.ip = htonl(ip); e.ip = htonl(ip);
last = ip_set_range_to_cidr(ip, ip_to, &e.cidr); last = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
ret = adtfn(set, &e, &ext, &ext, flags); ret = adtfn(set, &e, &ext, &ext, flags);

View File

@ -255,7 +255,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
if (retried) if (retried)
ip = ntohl(h->next.ip); ip = ntohl(h->next.ip);
while (!after(ip, ip_to)) { while (ip <= ip_to) {
e.ip = htonl(ip); e.ip = htonl(ip);
last = ip_set_range_to_cidr(ip, ip_to, &e.cidr); last = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
ret = adtfn(set, &e, &ext, &ext, flags); ret = adtfn(set, &e, &ext, &ext, flags);

View File

@ -250,13 +250,13 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
if (retried) if (retried)
ip = ntohl(h->next.ip[0]); ip = ntohl(h->next.ip[0]);
while (!after(ip, ip_to)) { while (ip <= ip_to) {
e.ip[0] = htonl(ip); e.ip[0] = htonl(ip);
last = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]); last = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]);
ip2 = (retried && ip2 = (retried &&
ip == ntohl(h->next.ip[0])) ? ntohl(h->next.ip[1]) ip == ntohl(h->next.ip[0])) ? ntohl(h->next.ip[1])
: ip2_from; : ip2_from;
while (!after(ip2, ip2_to)) { while (ip2 <= ip2_to) {
e.ip[1] = htonl(ip2); e.ip[1] = htonl(ip2);
last2 = ip_set_range_to_cidr(ip2, ip2_to, &e.cidr[1]); last2 = ip_set_range_to_cidr(ip2, ip2_to, &e.cidr[1]);
ret = adtfn(set, &e, &ext, &ext, flags); ret = adtfn(set, &e, &ext, &ext, flags);

View File

@ -241,7 +241,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
if (retried) if (retried)
ip = ntohl(h->next.ip); ip = ntohl(h->next.ip);
while (!after(ip, ip_to)) { while (ip <= ip_to) {
e.ip = htonl(ip); e.ip = htonl(ip);
last = ip_set_range_to_cidr(ip, ip_to, &cidr); last = ip_set_range_to_cidr(ip, ip_to, &cidr);
e.cidr = cidr - 1; e.cidr = cidr - 1;

View File

@ -291,7 +291,7 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
if (retried) if (retried)
ip = ntohl(h->next.ip[0]); ip = ntohl(h->next.ip[0]);
while (!after(ip, ip_to)) { while (ip <= ip_to) {
e.ip[0] = htonl(ip); e.ip[0] = htonl(ip);
ip_last = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]); ip_last = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]);
p = retried && ip == ntohl(h->next.ip[0]) ? ntohs(h->next.port) p = retried && ip == ntohl(h->next.ip[0]) ? ntohs(h->next.port)
@ -301,7 +301,7 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
ip2 = (retried && ip == ntohl(h->next.ip[0]) && ip2 = (retried && ip == ntohl(h->next.ip[0]) &&
p == ntohs(h->next.port)) ? ntohl(h->next.ip[1]) p == ntohs(h->next.port)) ? ntohl(h->next.ip[1])
: ip2_from; : ip2_from;
while (!after(ip2, ip2_to)) { while (ip2 <= ip2_to) {
e.ip[1] = htonl(ip2); e.ip[1] = htonl(ip2);
ip2_last = ip_set_range_to_cidr(ip2, ip2_to, ip2_last = ip_set_range_to_cidr(ip2, ip2_to,
&e.cidr[1]); &e.cidr[1]);