Skip to content

Commit

Permalink
net/tls: Protect from calling tls_dev_del for TLS RX twice
Browse files Browse the repository at this point in the history
tls_device_offload_cleanup_rx doesn't clear tls_ctx->netdev after
calling tls_dev_del if TLX TX offload is also enabled. Clearing
tls_ctx->netdev gets postponed until tls_device_gc_task. It leaves a
time frame when tls_device_down may get called and call tls_dev_del for
RX one extra time, confusing the driver, which may lead to a crash.

This patch corrects this racy behavior by adding a flag to prevent
tls_device_down from calling tls_dev_del the second time.

Fixes: e8f6979 ("net/tls: Add generic NIC offload infrastructure")
Signed-off-by: Maxim Mikityanskiy <[email protected]>
Signed-off-by: Saeed Mahameed <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
Maxim Mikityanskiy authored and kuba-moo committed Nov 26, 2020
1 parent a060133 commit 025cc2f
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 1 deletion.
6 changes: 6 additions & 0 deletions include/net/tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,12 @@ enum tls_context_flags {
* to be atomic.
*/
TLS_TX_SYNC_SCHED = 1,
/* 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
* tls_dev_del call in tls_device_down if it happens simultaneously.
*/
TLS_RX_DEV_CLOSED = 2,
};

struct cipher_context {
Expand Down
5 changes: 4 additions & 1 deletion net/tls/tls_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,8 @@ void tls_device_offload_cleanup_rx(struct sock *sk)
if (tls_ctx->tx_conf != TLS_HW) {
dev_put(netdev);
tls_ctx->netdev = NULL;
} else {
set_bit(TLS_RX_DEV_CLOSED, &tls_ctx->flags);
}
out:
up_read(&device_offload_lock);
Expand Down Expand Up @@ -1291,7 +1293,8 @@ static int tls_device_down(struct net_device *netdev)
if (ctx->tx_conf == TLS_HW)
netdev->tlsdev_ops->tls_dev_del(netdev, ctx,
TLS_OFFLOAD_CTX_DIR_TX);
if (ctx->rx_conf == TLS_HW)
if (ctx->rx_conf == TLS_HW &&
!test_bit(TLS_RX_DEV_CLOSED, &ctx->flags))
netdev->tlsdev_ops->tls_dev_del(netdev, ctx,
TLS_OFFLOAD_CTX_DIR_RX);
WRITE_ONCE(ctx->netdev, NULL);
Expand Down

0 comments on commit 025cc2f

Please sign in to comment.