Commit e1512c1d authored by Hyunwoo Kim's avatar Hyunwoo Kim Committed by Jakub Kicinski
Browse files

espintcp: Fix race condition in espintcp_close()



This issue was discovered during a code audit.

After cancel_work_sync() is called from espintcp_close(),
espintcp_tx_work() can still be scheduled from paths such as
the Delayed ACK handler or ksoftirqd.
As a result, the espintcp_tx_work() worker may dereference a
freed espintcp ctx or sk.

The following is a simple race scenario:

           cpu0                             cpu1

  espintcp_close()
    cancel_work_sync(&ctx->work);
                                     espintcp_write_space()
                                       schedule_work(&ctx->work);

To prevent this race condition, cancel_work_sync() is
replaced with disable_work_sync().

Fixes: e27cca96 ("xfrm: add espintcp (RFC 8229)")
Signed-off-by: default avatarHyunwoo Kim <imv4bel@gmail.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://patch.msgid.link/aZSie7rEdh9Nu0eM@v4bel


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f891007a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -536,7 +536,7 @@ static void espintcp_close(struct sock *sk, long timeout)
	sk->sk_prot = &tcp_prot;
	barrier();

	cancel_work_sync(&ctx->work);
	disable_work_sync(&ctx->work);
	strp_done(&ctx->strp);

	skb_queue_purge(&ctx->out_queue);