]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
netfilter: nfnetlink_queue: no longer acquire sk_callback_lock
authorEric Dumazet <edumazet@google.com>
Thu, 26 Feb 2026 09:40:36 +0000 (09:40 +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
nfqnl_put_sk_uidgid() 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/nfnetlink_queue.c

index 7f5248b5f1ee0a587f11eff2b47f1cd78a8746e2..27300d3663dad6d635acf60fa137ffb5ac29294c 100644 (file)
@@ -545,14 +545,23 @@ nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet,
 
 static int nfqnl_put_sk_uidgid(struct sk_buff *skb, struct sock *sk)
 {
+       const struct socket *sock;
+       const struct file *file;
        const struct cred *cred;
 
        if (!sk_fullsock(sk))
                return 0;
 
-       read_lock_bh(&sk->sk_callback_lock);
-       if (sk->sk_socket && sk->sk_socket->file) {
-               cred = sk->sk_socket->file->f_cred;
+       /* 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) {
+               cred = file->f_cred;
                if (nla_put_be32(skb, NFQA_UID,
                    htonl(from_kuid_munged(&init_user_ns, cred->fsuid))))
                        goto nla_put_failure;
@@ -560,11 +569,9 @@ static int nfqnl_put_sk_uidgid(struct sk_buff *skb, struct sock *sk)
                    htonl(from_kgid_munged(&init_user_ns, cred->fsgid))))
                        goto nla_put_failure;
        }
-       read_unlock_bh(&sk->sk_callback_lock);
        return 0;
 
 nla_put_failure:
-       read_unlock_bh(&sk->sk_callback_lock);
        return -1;
 }