Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 481186ca authored by Eric Dumazet's avatar Eric Dumazet Committed by Greg Kroah-Hartman
Browse files

net: annotate data-races around sk->sk_max_pacing_rate



[ Upstream commit ea7f45ef77b39e72244d282e47f6cb1ef4135cd2 ]

sk_getsockopt() runs locklessly. This means sk->sk_max_pacing_rate
can be read while other threads are changing its value.

Fixes: 62748f32 ("net: introduce SO_MAX_PACING_RATE")
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>
parent 1774250a
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -1117,7 +1117,8 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
			cmpxchg(&sk->sk_pacing_status,
				SK_PACING_NONE,
				SK_PACING_NEEDED);
		sk->sk_max_pacing_rate = ulval;
		/* Pairs with READ_ONCE() from sk_getsockopt() */
		WRITE_ONCE(sk->sk_max_pacing_rate, ulval);
		sk->sk_pacing_rate = min(sk->sk_pacing_rate, ulval);
		break;
		}
@@ -1478,12 +1479,14 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
#endif

	case SO_MAX_PACING_RATE:
		/* The READ_ONCE() pair with the WRITE_ONCE() in sk_setsockopt() */
		if (sizeof(v.ulval) != sizeof(v.val) && len >= sizeof(v.ulval)) {
			lv = sizeof(v.ulval);
			v.ulval = sk->sk_max_pacing_rate;
			v.ulval = READ_ONCE(sk->sk_max_pacing_rate);
		} else {
			/* 32bit version */
			v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U);
			v.val = min_t(unsigned long, ~0U,
				      READ_ONCE(sk->sk_max_pacing_rate));
		}
		break;