From: Maxim Mikityanskiy maximmi@nvidia.com
mainline inclusion from mainline-v5.13-rc5 commit 05fc8b6cbd4f979a6f25759c4a17dd5f657f7ecd category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I990AF CVE: CVE-2021-47131
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
RCU synchronization is guaranteed to finish in finite time, unlike a busy loop that polls a flag. This patch is a preparation for the bugfix in the next patch, where the same synchronize_net() call will also be used to sync with the TX datapath.
Signed-off-by: Maxim Mikityanskiy maximmi@nvidia.com Reviewed-by: Tariq Toukan tariqt@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Conflicts: include/net/tls.h net/tls/tls_device.c Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com --- include/net/tls.h | 1 - net/tls/tls_device.c | 9 +++------ 2 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/include/net/tls.h b/include/net/tls.h index e2d84b791e5ca..bf7af80e682f8 100644 --- a/include/net/tls.h +++ b/include/net/tls.h @@ -169,7 +169,6 @@ enum { };
enum tls_context_flags { - TLS_RX_SYNC_RUNNING = 0, /* tls_dev_del was called for the RX side, device state was released, * but tls_ctx->netdev might still be kept, because TX-side driver * resources might not be released yet. Used to prevent the second diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c index 228e3ce48d437..a4d3c5462d058 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c @@ -571,12 +571,11 @@ static void tls_device_resync_rx(struct tls_context *tls_ctx, { struct net_device *netdev;
- if (WARN_ON(test_and_set_bit(TLS_RX_SYNC_RUNNING, &tls_ctx->flags))) - return; + rcu_read_lock(); netdev = READ_ONCE(tls_ctx->netdev); if (netdev) netdev->tlsdev_ops->tls_dev_resync_rx(netdev, sk, seq, rcd_sn); - clear_bit_unlock(TLS_RX_SYNC_RUNNING, &tls_ctx->flags); + rcu_read_unlock(); }
void handle_device_resync(struct sock *sk, u32 seq, u64 rcd_sn) @@ -991,9 +990,7 @@ static int tls_device_down(struct net_device *netdev) netdev->tlsdev_ops->tls_dev_del(netdev, ctx, TLS_OFFLOAD_CTX_DIR_RX); WRITE_ONCE(ctx->netdev, NULL); - smp_mb__before_atomic(); /* pairs with test_and_set_bit() */ - while (test_bit(TLS_RX_SYNC_RUNNING, &ctx->flags)) - usleep_range(10, 200); + synchronize_net(); dev_put(netdev); list_del_init(&ctx->list);