aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2023-07-28 15:03:10 +0000
committerDavid S. Miller <davem@davemloft.net>2023-07-29 18:13:41 +0100
commitea7f45ef77b39e72244d282e47f6cb1ef4135cd2 (patch)
tree5bdc4e61b408719dc8d8d31a92120aaf6644e4fe
parentc76a0328899bbe226f8adeb88b8da9e4167bd316 (diff)
downloadkvm-s390-vfio-ea7f45ef77b39e72244d282e47f6cb1ef4135cd2.tar.gz
net: annotate data-races around sk->sk_max_pacing_rate
sk_getsockopt() runs locklessly. This means sk->sk_max_pacing_rate can be read while other threads are changing its value. Fixes: 62748f32d501 ("net: introduce SO_MAX_PACING_RATE") Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/core/sock.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/net/core/sock.c b/net/core/sock.c
index adec93dda56af7..fec18755f77272 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1439,7 +1439,8 @@ set_sndbuf:
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;
}
@@ -1903,12 +1904,14 @@ int sk_getsockopt(struct sock *sk, 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;