Skip to content

Commit 0d87bbd

Browse files
kuba-moodavem330
authored andcommitted
tls: strp: make sure the TCP skbs do not have overlapping data
TLS tries to get away with using the TCP input queue directly. This does not work if there is duplicated data (multiple skbs holding bytes for the same seq number range due to retransmits). Check for this condition and fall back to copy mode, it should be rare. Fixes: 84c61fe ("tls: rx: do not use the standard strparser") Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent aae425e commit 0d87bbd

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

net/tls/tls_strp.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ static int tls_strp_read_copyin(struct tls_strparser *strp)
273273
return desc.error;
274274
}
275275

276-
static int tls_strp_read_short(struct tls_strparser *strp)
276+
static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort)
277277
{
278278
struct skb_shared_info *shinfo;
279279
struct page *page;
@@ -283,7 +283,7 @@ static int tls_strp_read_short(struct tls_strparser *strp)
283283
* to read the data out. Otherwise the connection will stall.
284284
* Without pressure threshold of INT_MAX will never be ready.
285285
*/
286-
if (likely(!tcp_epollin_ready(strp->sk, INT_MAX)))
286+
if (likely(qshort && !tcp_epollin_ready(strp->sk, INT_MAX)))
287287
return 0;
288288

289289
shinfo = skb_shinfo(strp->anchor);
@@ -315,6 +315,27 @@ static int tls_strp_read_short(struct tls_strparser *strp)
315315
return 0;
316316
}
317317

318+
static bool tls_strp_check_no_dup(struct tls_strparser *strp)
319+
{
320+
unsigned int len = strp->stm.offset + strp->stm.full_len;
321+
struct sk_buff *skb;
322+
u32 seq;
323+
324+
skb = skb_shinfo(strp->anchor)->frag_list;
325+
seq = TCP_SKB_CB(skb)->seq;
326+
327+
while (skb->len < len) {
328+
seq += skb->len;
329+
len -= skb->len;
330+
skb = skb->next;
331+
332+
if (TCP_SKB_CB(skb)->seq != seq)
333+
return false;
334+
}
335+
336+
return true;
337+
}
338+
318339
static void tls_strp_load_anchor_with_queue(struct tls_strparser *strp, int len)
319340
{
320341
struct tcp_sock *tp = tcp_sk(strp->sk);
@@ -373,7 +394,7 @@ static int tls_strp_read_sock(struct tls_strparser *strp)
373394
return tls_strp_read_copyin(strp);
374395

375396
if (inq < strp->stm.full_len)
376-
return tls_strp_read_short(strp);
397+
return tls_strp_read_copy(strp, true);
377398

378399
if (!strp->stm.full_len) {
379400
tls_strp_load_anchor_with_queue(strp, inq);
@@ -387,9 +408,12 @@ static int tls_strp_read_sock(struct tls_strparser *strp)
387408
strp->stm.full_len = sz;
388409

389410
if (!strp->stm.full_len || inq < strp->stm.full_len)
390-
return tls_strp_read_short(strp);
411+
return tls_strp_read_copy(strp, true);
391412
}
392413

414+
if (!tls_strp_check_no_dup(strp))
415+
return tls_strp_read_copy(strp, false);
416+
393417
strp->msg_ready = 1;
394418
tls_rx_msg_ready(strp);
395419

0 commit comments

Comments
 (0)