Skip to content

Commit

Permalink
tls: don't skip over different type records from the rx_list
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
qsn authored and kuba-moo committed Feb 21, 2024
1 parent fdfbaec commit ec823bf
Showing 1 changed file with 14 additions and 8 deletions.
22 changes: 14 additions & 8 deletions net/tls/tls_sw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1772,7 +1772,8 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,
u8 *control,
size_t skip,
size_t len,
bool is_peek)
bool is_peek,
bool *more)
{
struct sk_buff *skb = skb_peek(&ctx->rx_list);
struct tls_msg *tlm;
Expand All @@ -1785,7 +1786,7 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,

err = tls_record_content_type(msg, tlm, control);
if (err <= 0)
goto out;
goto more;

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

err = tls_record_content_type(msg, tlm, control);
if (err <= 0)
goto out;
goto more;

err = skb_copy_datagram_msg(skb, rxm->offset + skip,
msg, chunk);
if (err < 0)
goto out;
goto more;

len = len - chunk;
copied = copied + chunk;
Expand Down Expand Up @@ -1844,6 +1845,10 @@ static int process_rx_list(struct tls_sw_context_rx *ctx,

out:
return copied ? : err;
more:
if (more)
*more = true;
goto out;
}

static bool
Expand Down Expand Up @@ -1947,6 +1952,7 @@ int tls_sw_recvmsg(struct sock *sk,
int target, err;
bool is_kvec = iov_iter_is_kvec(&msg->msg_iter);
bool is_peek = flags & MSG_PEEK;
bool rx_more = false;
bool released = true;
bool bpf_strp_enabled;
bool zc_capable;
Expand All @@ -1966,12 +1972,12 @@ int tls_sw_recvmsg(struct sock *sk,
goto end;

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

copied = err;
if (len <= copied || (copied && control != TLS_RECORD_TYPE_DATA))
if (len <= copied || (copied && control != TLS_RECORD_TYPE_DATA) || rx_more)
goto end;

target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
Expand Down Expand Up @@ -2130,10 +2136,10 @@ int tls_sw_recvmsg(struct sock *sk,
/* Drain records from the rx_list & copy if required */
if (is_peek || is_kvec)
err = process_rx_list(ctx, msg, &control, copied,
decrypted, is_peek);
decrypted, is_peek, NULL);
else
err = process_rx_list(ctx, msg, &control, 0,
async_copy_bytes, is_peek);
async_copy_bytes, is_peek, NULL);
}

copied += decrypted;
Expand Down

0 comments on commit ec823bf

Please sign in to comment.