]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
netfilter: nft_meta: no longer acquire sk_callback_lock in nft_meta_get_eval_skugid()
authorEric Dumazet <edumazet@google.com>
Thu, 26 Feb 2026 08:29:22 +0000 (08:29 +0000)
committerFlorian Westphal <fw@strlen.de>
Wed, 4 Mar 2026 10:45:44 +0000 (11:45 +0100)
After commit 983512f3a87f ("net: Drop the lock in skb_may_tx_timestamp()")
from Sebastian Andrzej Siewior, apply the same logic in
nft_meta_get_eval_skugid() to avoid touching sk->sk_callback_lock.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/nft_meta.c

index 983158274c68dc6626032e6f55afc452c4be443f..d0df6cf374d1abe83ce2a02d93fb366e12b3d8d2 100644 (file)
@@ -131,33 +131,36 @@ nft_meta_get_eval_skugid(enum nft_meta_keys key,
                         u32 *dest,
                         const struct nft_pktinfo *pkt)
 {
-       struct sock *sk = skb_to_full_sk(pkt->skb);
-       struct socket *sock;
+       const struct sock *sk = skb_to_full_sk(pkt->skb);
+       const struct socket *sock;
+       const struct file *file;
 
        if (!sk || !sk_fullsock(sk) || !net_eq(nft_net(pkt), sock_net(sk)))
                return false;
 
-       read_lock_bh(&sk->sk_callback_lock);
-       sock = sk->sk_socket;
-       if (!sock || !sock->file) {
-               read_unlock_bh(&sk->sk_callback_lock);
+       /* The sk pointer remains valid as long as the skb is. The sk_socket and
+        * file pointer may become NULL if the socket is closed. Both structures
+        * (including file->cred) are RCU freed which means they can be accessed
+        * within a RCU read section.
+        */
+       sock = READ_ONCE(sk->sk_socket);
+       file = sock ? READ_ONCE(sock->file) : NULL;
+       if (!file)
                return false;
-       }
 
        switch (key) {
        case NFT_META_SKUID:
                *dest = from_kuid_munged(sock_net(sk)->user_ns,
-                                        sock->file->f_cred->fsuid);
+                                        file->f_cred->fsuid);
                break;
        case NFT_META_SKGID:
                *dest = from_kgid_munged(sock_net(sk)->user_ns,
-                                        sock->file->f_cred->fsgid);
+                                        file->f_cred->fsgid);
                break;
        default:
                break;
        }
 
-       read_unlock_bh(&sk->sk_callback_lock);
        return true;
 }