Commit 84a8335d authored by Chuck Lever's avatar Chuck Lever Committed by Paolo Abeni
Browse files

tls: Purge async_hold in tls_decrypt_async_wait()



The async_hold queue pins encrypted input skbs while
the AEAD engine references their scatterlist data. Once
tls_decrypt_async_wait() returns, every AEAD operation
has completed and the engine no longer references those
skbs, so they can be freed unconditionally.

A subsequent patch adds batch async decryption to
tls_sw_read_sock(), introducing a new call site that
must drain pending AEAD operations and release held
skbs. Move __skb_queue_purge(&ctx->async_hold) into
tls_decrypt_async_wait() so the purge is centralized
and every caller -- recvmsg's drain path, the -EBUSY
fallback in tls_do_decryption(), and the new read_sock
batch path -- releases held skbs on synchronization
without each site managing the purge independently.

This fixes a leak when tls_strp_msg_hold() fails part-way through,
after having added some cloned skbs to the async_hold
queue. tls_decrypt_sg() will then call tls_decrypt_async_wait() to
process all pending decrypts, and drop back to synchronous mode, but
tls_sw_recvmsg() only flushes the async_hold queue when one record has
been processed in "fully-async" mode, which may not be the case here.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Reported-by: default avatarYiming Qian <yimingqian591@gmail.com>
Fixes: b8a6ff84 ("tls: wait for pending async decryptions if tls_strp_msg_hold fails")
Link: https://patch.msgid.link/20260324-tls-read-sock-v5-1-5408befe5774@oracle.com


[pabeni@redhat.com: added leak comment]
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent c4ea7d89
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -246,6 +246,7 @@ static int tls_decrypt_async_wait(struct tls_sw_context_rx *ctx)
		crypto_wait_req(-EINPROGRESS, &ctx->async_wait);
	atomic_inc(&ctx->decrypt_pending);

	__skb_queue_purge(&ctx->async_hold);
	return ctx->async_wait.err;
}

@@ -2225,7 +2226,6 @@ int tls_sw_recvmsg(struct sock *sk,

		/* Wait for all previously submitted records to be decrypted */
		ret = tls_decrypt_async_wait(ctx);
		__skb_queue_purge(&ctx->async_hold);

		if (ret) {
			if (err >= 0 || err == -EINPROGRESS)