diff --git a/include/net/tls.h b/include/net/tls.h
index e57bef58851e..0b001b8ab1c3 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -139,6 +139,7 @@ struct tls_sw_context_rx {
u8 zc_capable:1;
u8 reader_contended:1;
bool key_update_pending;
+ u8 empty_run;
struct tls_strparser strp;
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index 771e02bff519..adf3b26b8a75 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -1146,6 +1146,7 @@ tls_rx_rec_wait(struct sock *sk, bool nonblock, bool released, bool has_copied)
if (!timeo)
return -EAGAIN;
+ ctx->empty_run = 0;
released = true;
add_wait_queue(sk_sleep(sk), &wait);
sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
@@ -1565,6 +1566,7 @@ static int tls_rx_one_record(struct sock *sk, struct msghdr *msg,
struct tls_decrypt_arg *darg)
{
struct tls_context *tls_ctx = tls_get_ctx(sk);
+ struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
struct tls_prot_info *prot = &tls_ctx->prot_info;
struct strp_msg *rxm;
int err;@@ -1582,6 +1584,19 @@ static int tls_rx_one_record(struct sock *sk, struct msghdr *msg,
rxm->full_len -= prot->overhead_size;
tls_advance_record_sn(sk, prot, &tls_ctx->rx);
+ /* A peer may send empty data records, e.g. as cover traffic, but
+ * a burst of them traps the reader in the kernel. Treat more than
+ * 128 in a row, without the reader sleeping or returning to the
+ * caller in between, as a protocol violation. Stop the strparser
+ * before the next record gets parsed, so the reader finds the
+ * error in tls_rx_rec_wait().
+ */
+ if (rxm->full_len ||
+ tls_msg(darg->skb)->control != TLS_RECORD_TYPE_DATA)
+ ctx->empty_run = 0;
+ else if (unlikely(++ctx->empty_run > 128))
+ tls_strp_abort_strp(&ctx->strp, -EBADMSG);
+
return tls_check_pending_rekey(sk, tls_ctx, darg->skb);
}
@@ -1761,6 +1776,7 @@ static int tls_rx_reader_acquire(struct sock *sk, struct tls_sw_context_rx *ctx,
}
WRITE_ONCE(ctx->reader_present, 1);
+ ctx->empty_run = 0;
return 0;
}
@@ -1874,9 +1890,11 @@ int tls_sw_recvmsg(struct sock *sk,
tlm->control == TLS_RECORD_TYPE_DATA)
darg.zc = true;
- /* Do not use async mode if record is non-data */
+ /* Do not use async mode if record is non-data or empty,
+ * recv_end would report an error after empty records as EOF.
+ */
if (tlm->control == TLS_RECORD_TYPE_DATA)
- darg.async = ctx->async_capable;
+ darg.async = ctx->async_capable && to_decrypt;
else
darg.async = false;
@@ -1918,7 +1936,10 @@ int tls_sw_recvmsg(struct sock *sk,
DEBUG_NET_WARN_ON_ONCE(darg.skb == ctx->strp.anchor);
- if (async) {
+ /* Consume empty records, even when peeking, so that
+ * they cannot pile up on rx_list.
+ */
+ if (async && chunk) {
/* TLS 1.2-only, to_decrypt must be text len */
chunk = min_t(int, to_decrypt, len);
async_copy_bytes += chunk;@@ -1939,7 +1960,7 @@ int tls_sw_recvmsg(struct sock *sk,
if (err < 0)
goto put_on_rx_list_err;
- if (is_peek) {
+ if (is_peek && chunk) {
peeked += chunk;
goto put_on_rx_list;
}--
2.56.0