Commit afc2125d authored by Eric Dumazet's avatar Eric Dumazet Committed by Florian Westphal
Browse files

netfilter: nft_meta: no longer acquire sk_callback_lock in nft_meta_get_eval_skugid()



After commit 983512f3 ("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: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
parent cdec942a
Loading
Loading
Loading
Loading
+13 −10
Original line number Diff line number Diff line
@@ -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;
}