]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: annotate data-races around sk->sk_max_pacing_rate
authorEric Dumazet <edumazet@google.com>
Fri, 28 Jul 2023 15:03:10 +0000 (15:03 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 11 Aug 2023 13:13:51 +0000 (15:13 +0200)
[ 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: 62748f32d501 ("net: introduce SO_MAX_PACING_RATE")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/core/sock.c

index cf1e437ae48759162867d3b6a3b8f129ffd849fc..d392efa0d95516fad1cddf07deba3b385d94880a 100644 (file)
@@ -1297,7 +1297,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;
                }
@@ -1680,12 +1681,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;