[PATCH net v2 1/4] tls: device: fix record start in the tls_device_decrypted tracepoint
flat view
WARM1d
From: Rishikesh Jethwani <hidden>
Date: 2026-10-22 22:17:37
Also in:
lkml
Subsystem:
networking [general], networking [tls], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, John Fastabend, Sabrina Dubroca, Linus Torvalds
tls_device_decrypted() reports the TCP sequence of the record it is
classifying as tcp_sk(sk)->copied_seq - rxm->full_len. The original
strparser read every record out of the TCP receive queue before the TLS
layer looked at it, so copied_seq had already moved past the record.
The TLS-specific strparser leaves the record in the TCP receive queue in
its normal mode and only calls tcp_read_done() from
tls_strp_msg_consume(), after decryption. When the tracepoint fires,
copied_seq still points at the first byte of the record, and the
reported tcp_seq is one record length too low.
In copy mode (e.g. when the receive queue is short under memory
pressure or with a collapsed receive window, or the record spans
overlapping or mixed decrypted/undecrypted skbs), tcp_read_sock() has
already advanced copied_seq past the record. It can also consume a FIN
that ends the record's last skb, which adds one byte of sequence space
absent from the record length, so subtracting the length reports a
start one byte too high. copied_seq cannot tell whether a FIN was
consumed, so the start must be saved before the read.
Record the TCP sequence in the strparser whenever it starts parsing a
new record, before anything can switch it to copy mode, and report that
via a new tls_strp_msg_seq() helper. The value is then valid in both
modes without having to track which path entered copy mode.
No functional change beyond the tracepoint argument.
Found by code inspection while working on TLS 1.3 hardware offload
support.
Fixes: 84c61fe1a75b ("tls: rx: do not use the standard strparser")
Signed-off-by: Rishikesh Jethwani <redacted>
---
include/net/tls.h | 2 ++
net/tls/tls.h | 6 ++++++
net/tls/tls_device.c | 2 +-
net/tls/tls_strp.c | 3 +++
4 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/include/net/tls.h b/include/net/tls.h
index e57bef58851e..e1e48a25cafa 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h@@ -123,6 +123,8 @@ struct tls_strparser { bool msg_ready; struct strp_msg stm; + /* TCP sequence of the first byte of the current record. */ + u32 seq; struct sk_buff *anchor; struct work_struct work;
diff --git a/net/tls/tls.h b/net/tls/tls.h
index 60a37bdaaa25..a9f7fd79c69e 100644
--- a/net/tls/tls.h
+++ b/net/tls/tls.h@@ -227,6 +227,12 @@ static inline bool tls_strp_msg_mixed_decrypted(struct tls_sw_context_rx *ctx) return ctx->strp.mixed_decrypted; } +static inline u32 tls_strp_msg_seq(struct tls_sw_context_rx *ctx) +{ + DEBUG_NET_WARN_ON_ONCE(!ctx->strp.msg_ready); + return ctx->strp.seq; +} + #ifdef CONFIG_TLS_DEVICE int tls_device_init(void); void tls_device_cleanup(void);
diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c
index f11d0528fc43..fbfe6ec3df04 100644
--- a/net/tls/tls_device.c
+++ b/net/tls/tls_device.c@@ -990,7 +990,7 @@ int tls_device_decrypted(struct sock *sk, struct tls_context *tls_ctx) is_encrypted = 0; } - trace_tls_device_decrypted(sk, tcp_sk(sk)->copied_seq - rxm->full_len, + trace_tls_device_decrypted(sk, tls_strp_msg_seq(sw_ctx), tls_ctx->rx.rec_seq, rxm->full_len, is_encrypted, is_decrypted);
diff --git a/net/tls/tls_strp.c b/net/tls/tls_strp.c
index 6cc222008d95..5d5e8c3fd5ad 100644
--- a/net/tls/tls_strp.c
+++ b/net/tls/tls_strp.c@@ -526,6 +526,9 @@ static int tls_strp_read_sock(struct tls_strparser *strp) tls_strp_load_anchor_with_queue(strp, inq); if (!strp->stm.full_len) { + /* Save the record start before copy mode advances copied_seq. */ + strp->seq = tcp_sk(strp->sk)->copied_seq; + if (inq < TLS_HEADER_SIZE) return tls_strp_read_copy(strp, true); if (!tls_strp_check_queue_ok(strp, TLS_HEADER_SIZE))
--
2.50.1