From: Chuck Lever The tls_sw_read_sock() loop releases the current skb whether read_actor() consumed the full record or only a prefix. When the actor takes only part of the record and leaves desc->count non-zero, the remainder is lost: skb is neither requeued nor freed, and the next iteration overwrites it during dequeue or tls_rx_rec_wait(). No mainline consumer reaches this path today. The only in-tree TLS read_sock user is nvme/tcp, whose actor nvme_tcp_recv_skb() loops until the input length is exhausted and returns either the full length or a negative error. The path becomes reachable with the upcoming NFSD svcsock receive built on read_sock_cmsg. Its data actor, svc_tcp_recv_actor(), parses an RPC fragment stream incrementally and returns at fragment boundaries. When a TLS record carries the tail of one RPC fragment plus the head of the next, the actor returns fewer bytes than offered while leaving desc->count non-zero, and without re-presentation the trailing fragment header vanishes. __tcp_read_sock() handles the equivalent case for plain TCP by leaving the unread bytes available for the next iteration to re-present, via sequence-number re-lookup. Adopt the same loop-level behavior: when read_actor() consumes only part of the record, update rxm->offset and rxm->full_len and requeue the skb to the head of rx_list so the next iteration re-presents the unread bytes. Switch the open-ended for-loop to "while (desc->count)" so the partial- and full-consume arms share a single exit check and read_actor() is not re-invoked once desc->count is exhausted. Cc: Sagi Grimberg Signed-off-by: Chuck Lever Reviewed-by: Hannes Reinecke Reviewed-by: Sabrina Dubroca --- net/tls/tls_sw.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 8e4e57721335..fd8d3c979368 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -2383,7 +2383,7 @@ int tls_sw_read_sock(struct sock *sk, read_descriptor_t *desc, goto read_sock_end; decrypted = 0; - for (;;) { + while (desc->count) { if (!skb_queue_empty(&ctx->rx_list)) { skb = __skb_dequeue(&ctx->rx_list); rxm = strp_msg(skb); @@ -2430,12 +2430,9 @@ int tls_sw_read_sock(struct sock *sk, read_descriptor_t *desc, if (used < rxm->full_len) { rxm->offset += used; rxm->full_len -= used; - if (!desc->count) - goto read_sock_requeue; + __skb_queue_head(&ctx->rx_list, skb); } else { consume_skb(skb); - if (!desc->count) - break; } } -- 2.54.0