]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
tls: don't rely on tx_work during send()
authorSabrina Dubroca <sd@queasysnail.net>
Tue, 14 Oct 2025 09:17:00 +0000 (11:17 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Oct 2025 13:03:08 +0000 (14:03 +0100)
[ Upstream commit 7f846c65ca11e63d2409868ff039081f80e42ae4 ]

With async crypto, we rely on tx_work to actually transmit records
once encryption completes. But while send() is running, both the
tx_lock and socket lock are held, so tx_work_handler cannot process
the queue of encrypted records, and simply reschedules itself. During
a large send(), this could last a long time, and use a lot of memory.

Transmit any pending encrypted records before restarting the main
loop of tls_sw_sendmsg_locked.

Fixes: a42055e8d2c3 ("net/tls: Add support for async encryption of records for performance")
Reported-by: Jann Horn <jannh@google.com>
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Link: https://patch.msgid.link/8396631478f70454b44afb98352237d33f48d34d.1760432043.git.sd@queasysnail.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/tls/tls_sw.c

index e08edfc639fd53629621e9b1d5d3b1f8e34a61df..110859f7e5e3e906471639489cb76965244e4e18 100644 (file)
@@ -1089,6 +1089,13 @@ alloc_encrypted:
                                else if (ret != -EAGAIN)
                                        goto send_end;
                        }
+
+                       /* Transmit if any encryptions have completed */
+                       if (test_and_clear_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) {
+                               cancel_delayed_work(&ctx->tx_work.work);
+                               tls_tx_records(sk, msg->msg_flags);
+                       }
+
                        continue;
 rollback_iter:
                        copied -= try_to_copy;
@@ -1143,6 +1150,12 @@ fallback_to_reg_send:
                                        goto send_end;
                                }
                        }
+
+                       /* Transmit if any encryptions have completed */
+                       if (test_and_clear_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) {
+                               cancel_delayed_work(&ctx->tx_work.work);
+                               tls_tx_records(sk, msg->msg_flags);
+                       }
                }
 
                continue;