Skip to content

Commit ec823bf

Browse files
qsnkuba-moo
authored andcommitted
tls: don't skip over different type records from the rx_list
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 <[email protected]> Link: https://lore.kernel.org/r/f00c0c0afa080c60f016df1471158c1caf983c34.1708007371.git.sd@queasysnail.net Signed-off-by: Jakub Kicinski <[email protected]>
1 parent fdfbaec commit ec823bf

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
@@ -1772,7 +1772,8 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,
17721772
u8 *control,
17731773
size_t skip,
17741774
size_t len,
1775-
bool is_peek)
1775+
bool is_peek,
1776+
bool *more)
17761777
{
17771778
struct sk_buff *skb = skb_peek(&ctx->rx_list);
17781779
struct tls_msg *tlm;
@@ -1785,7 +1786,7 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,
17851786

17861787
err = tls_record_content_type(msg, tlm, control);
17871788
if (err <= 0)
1788-
goto out;
1789+
goto more;
17891790

17901791
if (skip < rxm->full_len)
17911792
break;
@@ -1803,12 +1804,12 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,
18031804

18041805
err = tls_record_content_type(msg, tlm, control);
18051806
if (err <= 0)
1806-
goto out;
1807+
goto more;
18071808

18081809
err = skb_copy_datagram_msg(skb, rxm->offset + skip,
18091810
msg, chunk);
18101811
if (err < 0)
1811-
goto out;
1812+
goto more;
18121813

18131814
len = len - chunk;
18141815
copied = copied + chunk;
@@ -1844,6 +1845,10 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,
18441845

18451846
out:
18461847
return copied ? : err;
1848+
more:
1849+
if (more)
1850+
*more = true;
1851+
goto out;
18471852
}
18481853

18491854
static bool
@@ -1947,6 +1952,7 @@ int tls_sw_recvmsg(struct sock *sk,
19471952
int target, err;
19481953
bool is_kvec = iov_iter_is_kvec(&msg->msg_iter);
19491954
bool is_peek = flags & MSG_PEEK;
1955+
bool rx_more = false;
19501956
bool released = true;
19511957
bool bpf_strp_enabled;
19521958
bool zc_capable;
@@ -1966,12 +1972,12 @@ int tls_sw_recvmsg(struct sock *sk,
19661972
goto end;
19671973

19681974
/* Process pending decrypted records. It must be non-zero-copy */
1969-
err = process_rx_list(ctx, msg, &control, 0, len, is_peek);
1975+
err = process_rx_list(ctx, msg, &control, 0, len, is_peek, &rx_more);
19701976
if (err < 0)
19711977
goto end;
19721978

19731979
copied = err;
1974-
if (len <= copied || (copied && control != TLS_RECORD_TYPE_DATA))
1980+
if (len <= copied || (copied && control != TLS_RECORD_TYPE_DATA) || rx_more)
19751981
goto end;
19761982

19771983
target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
@@ -2130,10 +2136,10 @@ int tls_sw_recvmsg(struct sock *sk,
21302136
/* Drain records from the rx_list & copy if required */
21312137
if (is_peek || is_kvec)
21322138
err = process_rx_list(ctx, msg, &control, copied,
2133-
decrypted, is_peek);
2139+
decrypted, is_peek, NULL);
21342140
else
21352141
err = process_rx_list(ctx, msg, &control, 0,
2136-
async_copy_bytes, is_peek);
2142+
async_copy_bytes, is_peek, NULL);
21372143
}
21382144

21392145
copied += decrypted;

0 commit comments

Comments
 (0)