Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

netfilter: nf_log_syslog: no longer acquire sk_callback_lock in nf_log_dump_sk_uid_gid()

After commit 983512f3a87f ("net: Drop the lock in skb_may_tx_timestamp()")
from Sebastian Andrzej Siewior, apply the same logic in nf_log_dump_sk_uid_gid()
to avoid touching sk_callback_lock.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Florian Westphal <fw@strlen.de>

authored by

Eric Dumazet and committed by
Florian Westphal
5663ac3e 1c32b24c

+12 -4
+12 -4
net/netfilter/nf_log_syslog.c
··· 165 165 static void nf_log_dump_sk_uid_gid(struct net *net, struct nf_log_buf *m, 166 166 struct sock *sk) 167 167 { 168 + const struct socket *sock; 169 + const struct file *file; 170 + 168 171 if (!sk || !sk_fullsock(sk) || !net_eq(net, sock_net(sk))) 169 172 return; 170 173 171 - read_lock_bh(&sk->sk_callback_lock); 172 - if (sk->sk_socket && sk->sk_socket->file) { 173 - const struct cred *cred = sk->sk_socket->file->f_cred; 174 + /* The sk pointer remains valid as long as the skb is. The sk_socket and 175 + * file pointer may become NULL if the socket is closed. Both structures 176 + * (including file->cred) are RCU freed which means they can be accessed 177 + * within a RCU read section. 178 + */ 179 + sock = READ_ONCE(sk->sk_socket); 180 + file = sock ? READ_ONCE(sock->file) : NULL; 181 + if (file) { 182 + const struct cred *cred = file->f_cred; 174 183 175 184 nf_log_buf_add(m, "UID=%u GID=%u ", 176 185 from_kuid_munged(&init_user_ns, cred->fsuid), 177 186 from_kgid_munged(&init_user_ns, cred->fsgid)); 178 187 } 179 - read_unlock_bh(&sk->sk_callback_lock); 180 188 } 181 189 182 190 static noinline_for_stack int