Skip to content

Commit f460d1f

Browse files
committed
tls: don't skip over different type records from the rx_list
jira VULN-136507 cve-pre CVE-2025-39682 commit-author Sabrina Dubroca <sd@queasysnail.net> commit ec823bf If we queue 3 records: - record 1, type DATA - record 2, some other type - record 3, type DATA and do a recv(PEEK), the rx_list will contain the first two records. The next large recv will walk through the rx_list and copy data from record 1, then stop because record 2 is a different type. Since we haven't filled up our buffer, we will process the next available record. It's also DATA, so we can merge it with the current read. We shouldn't do that, since there was a record in between that we ignored. Add a flag to let process_rx_list inform tls_sw_recvmsg that it had more data available. Fixes: 692d7b5 ("tls: Fix recvmsg() to be able to peek across multiple records") Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://lore.kernel.org/r/f00c0c0afa080c60f016df1471158c1caf983c34.1708007371.git.sd@queasysnail.net Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit ec823bf) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
1 parent c29100a commit f460d1f

File tree

1 file changed

+14
-8
lines changed

1 file changed

+14
-8
lines changed

net/tls/tls_sw.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1751,7 +1751,8 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,
17511751
u8 *control,
17521752
size_t skip,
17531753
size_t len,
1754-
bool is_peek)
1754+
bool is_peek,
1755+
bool *more)
17551756
{
17561757
struct sk_buff *skb = skb_peek(&ctx->rx_list);
17571758
struct tls_msg *tlm;
@@ -1764,7 +1765,7 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,
17641765

17651766
err = tls_record_content_type(msg, tlm, control);
17661767
if (err <= 0)
1767-
goto out;
1768+
goto more;
17681769

17691770
if (skip < rxm->full_len)
17701771
break;
@@ -1782,12 +1783,12 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,
17821783

17831784
err = tls_record_content_type(msg, tlm, control);
17841785
if (err <= 0)
1785-
goto out;
1786+
goto more;
17861787

17871788
err = skb_copy_datagram_msg(skb, rxm->offset + skip,
17881789
msg, chunk);
17891790
if (err < 0)
1790-
goto out;
1791+
goto more;
17911792

17921793
len = len - chunk;
17931794
copied = copied + chunk;
@@ -1823,6 +1824,10 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,
18231824

18241825
out:
18251826
return copied ? : err;
1827+
more:
1828+
if (more)
1829+
*more = true;
1830+
goto out;
18261831
}
18271832

18281833
static bool
@@ -1918,6 +1923,7 @@ int tls_sw_recvmsg(struct sock *sk,
19181923
int target, err;
19191924
bool is_kvec = iov_iter_is_kvec(&msg->msg_iter);
19201925
bool is_peek = flags & MSG_PEEK;
1926+
bool rx_more = false;
19211927
bool released = true;
19221928
bool bpf_strp_enabled;
19231929
bool zc_capable;
@@ -1939,12 +1945,12 @@ int tls_sw_recvmsg(struct sock *sk,
19391945
goto end;
19401946

19411947
/* Process pending decrypted records. It must be non-zero-copy */
1942-
err = process_rx_list(ctx, msg, &control, 0, len, is_peek);
1948+
err = process_rx_list(ctx, msg, &control, 0, len, is_peek, &rx_more);
19431949
if (err < 0)
19441950
goto end;
19451951

19461952
copied = err;
1947-
if (len <= copied || (copied && control != TLS_RECORD_TYPE_DATA))
1953+
if (len <= copied || (copied && control != TLS_RECORD_TYPE_DATA) || rx_more)
19481954
goto end;
19491955

19501956
target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
@@ -2107,10 +2113,10 @@ int tls_sw_recvmsg(struct sock *sk,
21072113
/* Drain records from the rx_list & copy if required */
21082114
if (is_peek || is_kvec)
21092115
err = process_rx_list(ctx, msg, &control, copied,
2110-
decrypted, is_peek);
2116+
decrypted, is_peek, NULL);
21112117
else
21122118
err = process_rx_list(ctx, msg, &control, 0,
2113-
async_copy_bytes, is_peek);
2119+
async_copy_bytes, is_peek, NULL);
21142120
}
21152121

21162122
copied += decrypted;

0 commit comments

Comments
 (0)