diff options
author | Eric Dumazet <edumazet@google.com> | 2022-11-18 07:38:43 +0300 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2022-11-22 07:36:30 +0300 |
commit | 32634819ad37290b5d5a84bf8b71ef5e972c4a20 (patch) | |
tree | 93240c111c96da7c1cb1366afdf324d43c778eaa /net/core/sock_diag.c | |
parent | 2c45455ea1a32a45200562ad99f238aae34ce496 (diff) | |
download | linux-32634819ad37290b5d5a84bf8b71ef5e972c4a20.tar.xz |
net: fix __sock_gen_cookie()
I was mistaken how atomic64_try_cmpxchg(&sk_cookie, &res, new)
is working.
I was assuming @res would contain the final sk_cookie value,
regardless of the success of our cmpxchg()
We could do something like:
if (atomic64_try_cmpxchg(&sk_cookie, &res, new)
res = new;
But we can avoid a conditional and read sk_cookie again.
atomic64_cmpxchg(&sk_cookie, res, new);
res = atomic64_read(&sk_cookie);
Reported-by: coverity-bot <keescook+coverity-bot@chromium.org>
Addresses-Coverity-ID: 1527347 ("Error handling issues")
Fixes: 4ebf802cf1c6 ("net: __sock_gen_cookie() cleanup")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/r/20221118043843.3703186-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/core/sock_diag.c')
-rw-r--r-- | net/core/sock_diag.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index b11593cae5a0..b1e29e18d1d6 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c @@ -30,7 +30,10 @@ u64 __sock_gen_cookie(struct sock *sk) if (!res) { u64 new = gen_cookie_next(&sock_cookie); - atomic64_try_cmpxchg(&sk->sk_cookie, &res, new); + atomic64_cmpxchg(&sk->sk_cookie, res, new); + + /* Another thread might have changed sk_cookie before us. */ + res = atomic64_read(&sk->sk_cookie); } return res; } |