diff options
author | Jakub Kicinski <kuba@kernel.org> | 2023-05-24 22:17:41 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2023-05-26 10:35:58 +0100 |
commit | 8a0d57df8938e9fd2e99d47a85b7f37d86f91097 (patch) | |
tree | f3580e647acbd306ee043c6cc59a2c1d7315a423 /net/tls | |
parent | aa866ee4b15162ef92a567512f85c4357ca8e97f (diff) | |
download | linux-8a0d57df8938e9fd2e99d47a85b7f37d86f91097.tar.gz linux-8a0d57df8938e9fd2e99d47a85b7f37d86f91097.tar.bz2 linux-8a0d57df8938e9fd2e99d47a85b7f37d86f91097.zip |
tls: improve lockless access safety of tls_err_abort()
Most protos' poll() methods insert a memory barrier between
writes to sk_err and sk_error_report(). This dates back to
commit a4d258036ed9 ("tcp: Fix race in tcp_poll").
I guess we should do the same thing in TLS, tcp_poll() does
not hold the socket lock.
Fixes: 3c4d7559159b ("tls: kernel TLS support")
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tls')
-rw-r--r-- | net/tls/tls_strp.c | 4 | ||||
-rw-r--r-- | net/tls/tls_sw.c | 4 |
2 files changed, 6 insertions, 2 deletions
diff --git a/net/tls/tls_strp.c b/net/tls/tls_strp.c index da95abbb7ea3..f37f4a0fcd3c 100644 --- a/net/tls/tls_strp.c +++ b/net/tls/tls_strp.c @@ -20,7 +20,9 @@ static void tls_strp_abort_strp(struct tls_strparser *strp, int err) strp->stopped = 1; /* Report an error on the lower socket */ - strp->sk->sk_err = -err; + WRITE_ONCE(strp->sk->sk_err, -err); + /* Paired with smp_rmb() in tcp_poll() */ + smp_wmb(); sk_error_report(strp->sk); } diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 6e6a7c37d685..1a53c8f481e9 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -70,7 +70,9 @@ noinline void tls_err_abort(struct sock *sk, int err) { WARN_ON_ONCE(err >= 0); /* sk->sk_err should contain a positive error code. */ - sk->sk_err = -err; + WRITE_ONCE(sk->sk_err, -err); + /* Paired with smp_rmb() in tcp_poll() */ + smp_wmb(); sk_error_report(sk); } |