forked from mirrors/linux
		
	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:
		
							parent
							
								
									89fcbb564f
								
							
						
					
					
						commit
						48596a8ddc
					
				
					 10 changed files with 24 additions and 22 deletions
				
			
		| 
						 | 
				
			
			@ -123,13 +123,12 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
 | 
			
		|||
		return ret;
 | 
			
		||||
 | 
			
		||||
	ip &= ip_set_hostmask(h->netmask);
 | 
			
		||||
	e.ip = htonl(ip);
 | 
			
		||||
	if (e.ip == 0)
 | 
			
		||||
		return -IPSET_ERR_HASH_ELEM;
 | 
			
		||||
 | 
			
		||||
	if (adt == IPSET_TEST) {
 | 
			
		||||
		e.ip = htonl(ip);
 | 
			
		||||
		if (e.ip == 0)
 | 
			
		||||
			return -IPSET_ERR_HASH_ELEM;
 | 
			
		||||
	if (adt == IPSET_TEST)
 | 
			
		||||
		return adtfn(set, &e, &ext, &ext, flags);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ip_to = ip;
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
	if (retried)
 | 
			
		||||
	if (retried) {
 | 
			
		||||
		ip = ntohl(h->next.ip);
 | 
			
		||||
	for (; !before(ip_to, ip); ip += hosts) {
 | 
			
		||||
		e.ip = htonl(ip);
 | 
			
		||||
		if (e.ip == 0)
 | 
			
		||||
			return -IPSET_ERR_HASH_ELEM;
 | 
			
		||||
	}
 | 
			
		||||
	for (; ip <= ip_to;) {
 | 
			
		||||
		ret = adtfn(set, &e, &ext, &ext, flags);
 | 
			
		||||
 | 
			
		||||
		if (ret && !ip_set_eexist(ret, flags))
 | 
			
		||||
			return ret;
 | 
			
		||||
 | 
			
		||||
		ip += hosts;
 | 
			
		||||
		e.ip = htonl(ip);
 | 
			
		||||
		if (e.ip == 0)
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
		ret = 0;
 | 
			
		||||
	}
 | 
			
		||||
	return ret;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,7 +149,7 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
 | 
			
		|||
 | 
			
		||||
	if (retried)
 | 
			
		||||
		ip = ntohl(h->next.ip);
 | 
			
		||||
	for (; !before(ip_to, ip); ip++) {
 | 
			
		||||
	for (; ip <= ip_to; ip++) {
 | 
			
		||||
		e.ip = htonl(ip);
 | 
			
		||||
		ret = adtfn(set, &e, &ext, &ext, flags);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -178,7 +178,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
 | 
			
		|||
 | 
			
		||||
	if (retried)
 | 
			
		||||
		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)
 | 
			
		||||
						       : port;
 | 
			
		||||
		for (; p <= port_to; p++) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -185,7 +185,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
 | 
			
		|||
 | 
			
		||||
	if (retried)
 | 
			
		||||
		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)
 | 
			
		||||
						       : port;
 | 
			
		||||
		for (; p <= port_to; p++) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -271,7 +271,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 | 
			
		|||
 | 
			
		||||
	if (retried)
 | 
			
		||||
		ip = ntohl(h->next.ip);
 | 
			
		||||
	for (; !before(ip_to, ip); ip++) {
 | 
			
		||||
	for (; ip <= ip_to; ip++) {
 | 
			
		||||
		e.ip = htonl(ip);
 | 
			
		||||
		p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
 | 
			
		||||
						       : port;
 | 
			
		||||
| 
						 | 
				
			
			@ -281,7 +281,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 | 
			
		|||
			      ip == ntohl(h->next.ip) &&
 | 
			
		||||
			      p == ntohs(h->next.port)
 | 
			
		||||
				? ntohl(h->next.ip2) : ip2_from;
 | 
			
		||||
			while (!after(ip2, ip2_to)) {
 | 
			
		||||
			while (ip2 <= ip2_to) {
 | 
			
		||||
				e.ip2 = htonl(ip2);
 | 
			
		||||
				ip2_last = ip_set_range_to_cidr(ip2, ip2_to,
 | 
			
		||||
								&cidr);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -193,7 +193,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
 | 
			
		|||
	}
 | 
			
		||||
	if (retried)
 | 
			
		||||
		ip = ntohl(h->next.ip);
 | 
			
		||||
	while (!after(ip, ip_to)) {
 | 
			
		||||
	while (ip <= ip_to) {
 | 
			
		||||
		e.ip = htonl(ip);
 | 
			
		||||
		last = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
 | 
			
		||||
		ret = adtfn(set, &e, &ext, &ext, flags);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -255,7 +255,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
 | 
			
		|||
 | 
			
		||||
	if (retried)
 | 
			
		||||
		ip = ntohl(h->next.ip);
 | 
			
		||||
	while (!after(ip, ip_to)) {
 | 
			
		||||
	while (ip <= ip_to) {
 | 
			
		||||
		e.ip = htonl(ip);
 | 
			
		||||
		last = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
 | 
			
		||||
		ret = adtfn(set, &e, &ext, &ext, flags);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -250,13 +250,13 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 | 
			
		|||
	if (retried)
 | 
			
		||||
		ip = ntohl(h->next.ip[0]);
 | 
			
		||||
 | 
			
		||||
	while (!after(ip, ip_to)) {
 | 
			
		||||
	while (ip <= ip_to) {
 | 
			
		||||
		e.ip[0] = htonl(ip);
 | 
			
		||||
		last = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]);
 | 
			
		||||
		ip2 = (retried &&
 | 
			
		||||
		       ip == ntohl(h->next.ip[0])) ? ntohl(h->next.ip[1])
 | 
			
		||||
						   : ip2_from;
 | 
			
		||||
		while (!after(ip2, ip2_to)) {
 | 
			
		||||
		while (ip2 <= ip2_to) {
 | 
			
		||||
			e.ip[1] = htonl(ip2);
 | 
			
		||||
			last2 = ip_set_range_to_cidr(ip2, ip2_to, &e.cidr[1]);
 | 
			
		||||
			ret = adtfn(set, &e, &ext, &ext, flags);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -241,7 +241,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
 | 
			
		|||
 | 
			
		||||
	if (retried)
 | 
			
		||||
		ip = ntohl(h->next.ip);
 | 
			
		||||
	while (!after(ip, ip_to)) {
 | 
			
		||||
	while (ip <= ip_to) {
 | 
			
		||||
		e.ip = htonl(ip);
 | 
			
		||||
		last = ip_set_range_to_cidr(ip, ip_to, &cidr);
 | 
			
		||||
		e.cidr = cidr - 1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -291,7 +291,7 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 | 
			
		|||
	if (retried)
 | 
			
		||||
		ip = ntohl(h->next.ip[0]);
 | 
			
		||||
 | 
			
		||||
	while (!after(ip, ip_to)) {
 | 
			
		||||
	while (ip <= ip_to) {
 | 
			
		||||
		e.ip[0] = htonl(ip);
 | 
			
		||||
		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)
 | 
			
		||||
| 
						 | 
				
			
			@ -301,7 +301,7 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 | 
			
		|||
			ip2 = (retried && ip == ntohl(h->next.ip[0]) &&
 | 
			
		||||
			       p == ntohs(h->next.port)) ? ntohl(h->next.ip[1])
 | 
			
		||||
							 : ip2_from;
 | 
			
		||||
			while (!after(ip2, ip2_to)) {
 | 
			
		||||
			while (ip2 <= ip2_to) {
 | 
			
		||||
				e.ip[1] = htonl(ip2);
 | 
			
		||||
				ip2_last = ip_set_range_to_cidr(ip2, ip2_to,
 | 
			
		||||
								&e.cidr[1]);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue