Commit c2ff4dad authored by Eric Dumazet's avatar Eric Dumazet Committed by Yongqiang Liu
Browse files

net: annotate data-races around sk->sk_tx_queue_mapping

stable inclusion
from stable-v4.19.300
commit bd4f1843a141fc77995108b08d9cc07f67d5d894
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8UH13


CVE: NA

--------------------------------

[ Upstream commit 0bb4d124d34044179b42a769a0c76f389ae973b6 ]

This field can be read or written without socket lock being held.

Add annotations to avoid load-store tearing.

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarYongqiang Liu <liuyongqiang13@huawei.com>
parent be7367b3
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -1806,21 +1806,33 @@ static inline void sk_tx_queue_set(struct sock *sk, int tx_queue)
	/* sk_tx_queue_mapping accept only upto a 16-bit value */
	if (WARN_ON_ONCE((unsigned short)tx_queue >= USHRT_MAX))
		return;
	sk->sk_tx_queue_mapping = tx_queue;
	/* Paired with READ_ONCE() in sk_tx_queue_get() and
	 * other WRITE_ONCE() because socket lock might be not held.
	 */
	WRITE_ONCE(sk->sk_tx_queue_mapping, tx_queue);
}

#define NO_QUEUE_MAPPING	USHRT_MAX

static inline void sk_tx_queue_clear(struct sock *sk)
{
	sk->sk_tx_queue_mapping = NO_QUEUE_MAPPING;
	/* Paired with READ_ONCE() in sk_tx_queue_get() and
	 * other WRITE_ONCE() because socket lock might be not held.
	 */
	WRITE_ONCE(sk->sk_tx_queue_mapping, NO_QUEUE_MAPPING);
}

static inline int sk_tx_queue_get(const struct sock *sk)
{
	if (sk && sk->sk_tx_queue_mapping != NO_QUEUE_MAPPING)
		return sk->sk_tx_queue_mapping;
	if (sk) {
		/* Paired with WRITE_ONCE() in sk_tx_queue_clear()
		 * and sk_tx_queue_set().
		 */
		int val = READ_ONCE(sk->sk_tx_queue_mapping);

		if (val != NO_QUEUE_MAPPING)
			return val;
	}
	return -1;
}