2026-07-26, 20:33:33 -0400, Chuck Lever wrote:
> TLS 1.2 and TLS 1.3 both permit zero-length application_data
> records as a traffic-analysis countermeasure (RFC 5246, Section
> 6.2.1; RFC 8446, Section 5.1). Such a record decrypts to
> full_len == 0, so every arm of the receive loop reaches
> "decrypted += chunk" and "len -= chunk" with chunk == 0: len
> never reaches zero, and tls_strp_msg_ready() holds the second
> loop term true while the peer keeps records arriving. The peek
> arm and the async arm also queue each record on rx_list, which
> then grows without bound. tls_rx_rec_wait() returns without
> waiting whenever a record is already parsed, so its signal check
> never runs
So we should just move the signal check to the top of
tls_rx_rec_wait()'s loop? (just after all the existing error handling
code)
Then we don't need to add custom code everywhere, and we don't need to
do that much special handling for 0-length records.
> and no other test in the loop consults
> signal_pending(). A peer streaming empty records therefore holds
> the caller in recvmsg(), unresponsive to SIGKILL, until it stops.
>
[...]
> + /* An empty record advances neither loop bound, so a flood
> + * of them can be interrupted only here. On the zero-copy
> + * path darg.skb is the strparser anchor, already released
> + * by tls_rx_rec_done().
> + */
> + if (tls_rx_empty_data_rec(chunk, control)) {
> + long timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
> +
> + if (!darg.zc)
> + consume_skb(darg.skb);
I don't see why you need this special handling. Could you explain that?
> + /* An empty record still marks a boundary. */
> + msg->msg_flags |= MSG_EOR;
(note: I know that ship has sailed)
I don't think the way ktls handles MSG_EOR on RX makes any sense,
outside of non-DATA records. For non-DATA records, we only ever
process one per call, so it works out.
For DATA records, We set MSG_EOR when we process the end of a record,
and then we process part of the next record. MSG_EOR is still set,
eventhough we're not finishing the read at a record
boundary. Userspace has no way of knowing where that record boundary
was, or how many there may have been.
--
Sabrina