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: nft_meta: no longer acquire sk_callback_lock in nft_meta_get_eval_skugid()

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>

authored by

Eric Dumazet and committed by
Florian Westphal
afc2125d cdec942a

+13 -10
+13 -10
net/netfilter/nft_meta.c
··· 131 131 u32 *dest, 132 132 const struct nft_pktinfo *pkt) 133 133 { 134 - struct sock *sk = skb_to_full_sk(pkt->skb); 135 - struct socket *sock; 134 + const struct sock *sk = skb_to_full_sk(pkt->skb); 135 + const struct socket *sock; 136 + const struct file *file; 136 137 137 138 if (!sk || !sk_fullsock(sk) || !net_eq(nft_net(pkt), sock_net(sk))) 138 139 return false; 139 140 140 - read_lock_bh(&sk->sk_callback_lock); 141 - sock = sk->sk_socket; 142 - if (!sock || !sock->file) { 143 - read_unlock_bh(&sk->sk_callback_lock); 141 + /* The sk pointer remains valid as long as the skb is. The sk_socket and 142 + * file pointer may become NULL if the socket is closed. Both structures 143 + * (including file->cred) are RCU freed which means they can be accessed 144 + * within a RCU read section. 145 + */ 146 + sock = READ_ONCE(sk->sk_socket); 147 + file = sock ? READ_ONCE(sock->file) : NULL; 148 + if (!file) 144 149 return false; 145 - } 146 150 147 151 switch (key) { 148 152 case NFT_META_SKUID: 149 153 *dest = from_kuid_munged(sock_net(sk)->user_ns, 150 - sock->file->f_cred->fsuid); 154 + file->f_cred->fsuid); 151 155 break; 152 156 case NFT_META_SKGID: 153 157 *dest = from_kgid_munged(sock_net(sk)->user_ns, 154 - sock->file->f_cred->fsgid); 158 + file->f_cred->fsgid); 155 159 break; 156 160 default: 157 161 break; 158 162 } 159 163 160 - read_unlock_bh(&sk->sk_callback_lock); 161 164 return true; 162 165 } 163 166