]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
netfilter: ipset: stop hash:* range iteration at end
authorNan Li <tonanli66@gmail.com>
Tue, 12 May 2026 08:50:01 +0000 (16:50 +0800)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sat, 16 May 2026 11:21:15 +0000 (13:21 +0200)
The following hash set variants:

hash:ip,mark
hash:ip,port
hash:ip,port,ip
hash:ip,port,net

iterate IPv4 ranges with a 32-bit iterator.

The iterator must stop once the last address in the requested range has
been processed. Advancing it once more can move the traversal state past
the end of the request, so a later retry may continue from an unintended
position.

Handle the iterator increment explicitly at the end of the loop and stop
once the upper bound has been processed. This keeps the existing retry
behaviour intact for valid ranges while preventing traversal from
continuing past the original boundary.

Fixes: 48596a8ddc46 ("netfilter: ipset: Fix adding an IPv4 range containing more than 2^31 addresses")
Cc: stable@kernel.org
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Signed-off-by: Nan Li <tonanli66@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/ipset/ip_set_hash_ipmark.c
net/netfilter/ipset/ip_set_hash_ipport.c
net/netfilter/ipset/ip_set_hash_ipportip.c
net/netfilter/ipset/ip_set_hash_ipportnet.c

index a22ec1a6f6ec85b1c7c3cf04a824e02a1c74057c..e26ca2a370e348d4080b27b9e8d077b1c808e34e 100644 (file)
@@ -150,7 +150,7 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
 
        if (retried)
                ip = ntohl(h->next.ip);
-       for (; ip <= ip_to; ip++, i++) {
+       for (; ip <= ip_to; i++) {
                e.ip = htonl(ip);
                if (i > IPSET_MAX_RANGE) {
                        hash_ipmark4_data_next(&h->next, &e);
@@ -162,6 +162,10 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
                        return ret;
 
                ret = 0;
+
+               if (ip == ip_to)
+                       break;
+               ip++;
        }
        return ret;
 }
index e977b5a9c48dcb23c8d89f78f7e6c0ae2b3e266a..41ca24a22a026ddab370795f22cdf1016f1fed8d 100644 (file)
@@ -186,7 +186,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
 
        if (retried)
                ip = ntohl(h->next.ip);
-       for (; ip <= ip_to; ip++) {
+       for (; ip <= ip_to;) {
                p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
                                                       : port;
                for (; p <= port_to; p++, i++) {
@@ -203,6 +203,9 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
 
                        ret = 0;
                }
+               if (ip == ip_to)
+                       break;
+               ip++;
        }
        return ret;
 }
index 39a01934b1536d800b14a6cddc4175cf64126ee7..b9ac2efaa15c7a86be0be7823b91937bff4d1c9b 100644 (file)
@@ -182,7 +182,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
 
        if (retried)
                ip = ntohl(h->next.ip);
-       for (; ip <= ip_to; ip++) {
+       for (; ip <= ip_to;) {
                p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
                                                       : port;
                for (; p <= port_to; p++, i++) {
@@ -199,6 +199,9 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
 
                        ret = 0;
                }
+               if (ip == ip_to)
+                       break;
+               ip++;
        }
        return ret;
 }
index 5c6de605a9fb7fd13db6b3497685d39d47a25911..2d6652d43199a4f4f2d975f32138d91935b7716b 100644 (file)
@@ -274,7 +274,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
                p = port;
                ip2 = ip2_from;
        }
-       for (; ip <= ip_to; ip++) {
+       for (; ip <= ip_to;) {
                e.ip = htonl(ip);
                for (; p <= port_to; p++) {
                        e.port = htons(p);
@@ -298,6 +298,9 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
                        ip2 = ip2_from;
                }
                p = port;
+               if (ip == ip_to)
+                       break;
+               ip++;
        }
        return ret;
 }