]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
netfilter: nf_conncount: callers must hold rcu read lock
authorFlorian Westphal <fw@strlen.de>
Fri, 5 Jun 2026 13:11:19 +0000 (15:11 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sun, 14 Jun 2026 10:51:50 +0000 (12:51 +0200)
rcu_derefence_raw() should not have been used here, it concealed this bug.
Its used because struct rb_node lacks __rcu annotated pointers, so plain
rcu_derefence causes sparse warnings.

The major tradeoff is that rcu_derefence_raw() doesn't warn when the caller
isn't in a rcu read section.

Extend the rcu read lock scope accordingly and cause sparse warnings,
those warnings are the lesser evil.

Fixes: 11efd5cb04a1 ("openvswitch: Support conntrack zone limit")
Closes: https://sashiko.dev/#/patchset/20260603230610.7900-1-fw%40strlen.de
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_conncount.c
net/openvswitch/conntrack.c

index ab28b47395bd254f5f7c7728d2c6050133904ad8..81e4a4e20df5d6b134e33a3cc4619c91c3186b24 100644 (file)
@@ -499,7 +499,7 @@ count_tree(struct net *net,
        hash = jhash2(key, data->keylen, data->initval) % CONNCOUNT_SLOTS;
        root = &data->root[hash];
 
-       parent = rcu_dereference_raw(root->rb_node);
+       parent = rcu_dereference(root->rb_node);
        while (parent) {
                int diff;
 
@@ -507,9 +507,9 @@ count_tree(struct net *net,
 
                diff = key_diff(key, rbconn->key, data->keylen);
                if (diff < 0) {
-                       parent = rcu_dereference_raw(parent->rb_left);
+                       parent = rcu_dereference(parent->rb_left);
                } else if (diff > 0) {
-                       parent = rcu_dereference_raw(parent->rb_right);
+                       parent = rcu_dereference(parent->rb_right);
                } else {
                        int ret;
 
index 7c9256572284f81ad866754eec466998c81724be..c6fd9c424e8fea610a07a47a6404e1494561b243 100644 (file)
@@ -1797,10 +1797,10 @@ static int ovs_ct_limit_get_zone_limit(struct net *net,
                } else {
                        rcu_read_lock();
                        limit = ct_limit_get(info, zone);
-                       rcu_read_unlock();
 
                        err = __ovs_ct_limit_get_zone_limit(
                                net, info->data, zone, limit, reply);
+                       rcu_read_unlock();
                        if (err)
                                return err;
                }