[Devel] [PATCH RHEL7 COMMIT] ms/netfilter: ipset: regression in ip_set_hash_ip.c

Konstantin Khorenko khorenko at virtuozzo.com
Fri Jun 14 15:08:39 MSK 2024


The commit is pushed to "branch-rh7-3.10.0-1160.114.2.vz7.222.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.114.2.vz7.222.1
------>
commit e90654c0bf25eb7a3a90a98cacabcc5ebe6cee76
Author: Vishwanath Pai <vpai at akamai.com>
Date:   Wed Sep 28 14:26:50 2022 -0400

    ms/netfilter: ipset: regression in ip_set_hash_ip.c
    
    This patch introduced a regression: commit 48596a8ddc46 ("netfilter:
    ipset: Fix adding an IPv4 range containing more than 2^31 addresses")
    
    The variable e.ip is passed to adtfn() function which finally adds the
    ip address to the set. The patch above refactored the for loop and moved
    e.ip = htonl(ip) to the end of the for loop.
    
    What this means is that if the value of "ip" changes between the first
    assignement of e.ip and the forloop, then e.ip is pointing to a
    different ip address than "ip".
    
    Test case:
    $ ipset create jdtest_tmp hash:ip family inet hashsize 2048 maxelem 100000
    $ ipset add jdtest_tmp 10.0.1.1/31
    ipset v6.21.1: Element cannot be added to the set: it's already added
    
    The value of ip gets updated inside the  "else if (tb[IPSET_ATTR_CIDR])"
    block but e.ip is still pointing to the old value.
    
    mFixes: 48596a8ddc46 ("netfilter: ipset: Fix adding an IPv4 range containing more than 2^31 addresses")
    Reviewed-by: Joshua Hunt <johunt at akamai.com>
    Signed-off-by: Vishwanath Pai <vpai at akamai.com>
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
    
    Found (but does not fix it) in the scope of:
    https://virtuozzo.atlassian.net/browse/PSBM-155867
    
    (cherry picked from commit c7aa1a76d4a0a3c401025b60c401412bbb60f8c6)
    Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
 net/netfilter/ipset/ip_set_hash_ip.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
index 613eb212cb48..ce2aedabcd8b 100644
--- a/net/netfilter/ipset/ip_set_hash_ip.c
+++ b/net/netfilter/ipset/ip_set_hash_ip.c
@@ -147,18 +147,16 @@ 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);
-		e.ip = htonl(ip);
-	}
 	for (; ip <= ip_to;) {
+		e.ip = htonl(ip);
 		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)
+		if (ip == 0)
 			return 0;
 
 		ret = 0;


More information about the Devel mailing list