Skip to content

Commit f6252d7

Browse files
committed
tls: don't skip over different type records from the rx_list
jira VULN-136508 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: Marcin Wcisło <marcin.wcislo@conclusive.pl>
1 parent 7a0b5f9 commit f6252d7

1 file changed

Lines changed: 14 additions & 8 deletions

File tree

net/tls/tls_sw.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,7 +1811,8 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,
18111811
u8 *control,
18121812
size_t skip,
18131813
size_t len,
1814-
bool is_peek)
1814+
bool is_peek,
1815+
bool *more)
18151816
{
18161817
struct sk_buff *skb = skb_peek(&ctx->rx_list);
18171818
struct tls_msg *tlm;
@@ -1824,7 +1825,7 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,
18241825

18251826
err = tls_record_content_type(msg, tlm, control);
18261827
if (err <= 0)
1827-
goto out;
1828+
goto more;
18281829

18291830
if (skip < rxm->full_len)
18301831
break;
@@ -1842,12 +1843,12 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,
18421843

18431844
err = tls_record_content_type(msg, tlm, control);
18441845
if (err <= 0)
1845-
goto out;
1846+
goto more;
18461847

18471848
err = skb_copy_datagram_msg(skb, rxm->offset + skip,
18481849
msg, chunk);
18491850
if (err < 0)
1850-
goto out;
1851+
goto more;
18511852

18521853
len = len - chunk;
18531854
copied = copied + chunk;
@@ -1883,6 +1884,10 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,
18831884

18841885
out:
18851886
return copied ? : err;
1887+
more:
1888+
if (more)
1889+
*more = true;
1890+
goto out;
18861891
}
18871892

18881893
static bool
@@ -1987,6 +1992,7 @@ int tls_sw_recvmsg(struct sock *sk,
19871992
int target, err;
19881993
bool is_kvec = iov_iter_is_kvec(&msg->msg_iter);
19891994
bool is_peek = flags & MSG_PEEK;
1995+
bool rx_more = false;
19901996
bool released = true;
19911997
bool bpf_strp_enabled;
19921998
bool zc_capable;
@@ -2008,12 +2014,12 @@ int tls_sw_recvmsg(struct sock *sk,
20082014
goto end;
20092015

20102016
/* Process pending decrypted records. It must be non-zero-copy */
2011-
err = process_rx_list(ctx, msg, &control, 0, len, is_peek);
2017+
err = process_rx_list(ctx, msg, &control, 0, len, is_peek, &rx_more);
20122018
if (err < 0)
20132019
goto end;
20142020

20152021
copied = err;
2016-
if (len <= copied || (copied && control != TLS_RECORD_TYPE_DATA))
2022+
if (len <= copied || (copied && control != TLS_RECORD_TYPE_DATA) || rx_more)
20172023
goto end;
20182024

20192025
target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
@@ -2170,10 +2176,10 @@ int tls_sw_recvmsg(struct sock *sk,
21702176
/* Drain records from the rx_list & copy if required */
21712177
if (is_peek || is_kvec)
21722178
err = process_rx_list(ctx, msg, &control, copied,
2173-
decrypted, is_peek);
2179+
decrypted, is_peek, NULL);
21742180
else
21752181
err = process_rx_list(ctx, msg, &control, 0,
2176-
async_copy_bytes, is_peek);
2182+
async_copy_bytes, is_peek, NULL);
21772183
}
21782184

21792185
copied += decrypted;

0 commit comments

Comments
 (0)