]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfrm: policy: fix sparse warnings in xfrm_policy_{init,fini}
authorSabrina Dubroca <sd@queasysnail.net>
Mon, 9 Mar 2026 10:32:40 +0000 (11:32 +0100)
committerSteffen Klassert <steffen.klassert@secunet.com>
Thu, 12 Mar 2026 06:15:43 +0000 (07:15 +0100)
In xfrm_policy_init:
add rcu_assign_pointer to fix warning:
net/xfrm/xfrm_policy.c:4238:29: warning: incorrect type in assignment (different address spaces)
net/xfrm/xfrm_policy.c:4238:29:    expected struct hlist_head [noderef] __rcu *table
net/xfrm/xfrm_policy.c:4238:29:    got struct hlist_head *

add rcu_dereference_protected to silence warning:
net/xfrm/xfrm_policy.c:4265:36: warning: incorrect type in argument 1 (different address spaces)
net/xfrm/xfrm_policy.c:4265:36:    expected struct hlist_head *n
net/xfrm/xfrm_policy.c:4265:36:    got struct hlist_head [noderef] __rcu *table

The netns is being created, no concurrent access is possible yet.

In xfrm_policy_fini, net is going away, there shouldn't be any
concurrent changes to the hashtables, so we can use
rcu_dereference_protected to silence warnings:
net/xfrm/xfrm_policy.c:4291:17: warning: incorrect type in argument 1 (different address spaces)
net/xfrm/xfrm_policy.c:4291:17:    expected struct hlist_head const *h
net/xfrm/xfrm_policy.c:4291:17:    got struct hlist_head [noderef] __rcu *table
net/xfrm/xfrm_policy.c:4292:36: warning: incorrect type in argument 1 (different address spaces)
net/xfrm/xfrm_policy.c:4292:36:    expected struct hlist_head *n
net/xfrm/xfrm_policy.c:4292:36:    got struct hlist_head [noderef] __rcu *table

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
net/xfrm/xfrm_policy.c

index 5428185196a1ff7d59ebbf9b4ae095e7debab627..49de5a6f4b85b860b8611ca4e3ed1d74395ba17e 100644 (file)
@@ -4242,7 +4242,7 @@ static int __net_init xfrm_policy_init(struct net *net)
                net->xfrm.policy_count[XFRM_POLICY_MAX + dir] = 0;
 
                htab = &net->xfrm.policy_bydst[dir];
-               htab->table = xfrm_hash_alloc(sz);
+               rcu_assign_pointer(htab->table, xfrm_hash_alloc(sz));
                if (!htab->table)
                        goto out_bydst;
                htab->hmask = hmask;
@@ -4269,7 +4269,7 @@ out_bydst:
                struct xfrm_policy_hash *htab;
 
                htab = &net->xfrm.policy_bydst[dir];
-               xfrm_hash_free(htab->table, sz);
+               xfrm_hash_free(rcu_dereference_protected(htab->table, true), sz);
        }
        xfrm_hash_free(net->xfrm.policy_byidx, sz);
 out_byidx:
@@ -4295,8 +4295,8 @@ static void xfrm_policy_fini(struct net *net)
 
                htab = &net->xfrm.policy_bydst[dir];
                sz = (htab->hmask + 1) * sizeof(struct hlist_head);
-               WARN_ON(!hlist_empty(htab->table));
-               xfrm_hash_free(htab->table, sz);
+               WARN_ON(!hlist_empty(rcu_dereference_protected(htab->table, true)));
+               xfrm_hash_free(rcu_dereference_protected(htab->table, true), sz);
        }
 
        sz = (net->xfrm.policy_idx_hmask + 1) * sizeof(struct hlist_head);