Skip to content

Commit 138559b

Browse files
Tariq Toukankuba-moo
authored andcommitted
net/tls: Fix wrong record sn in async mode of device resync
In async_resync mode, we log the TCP seq of records until the async request is completed. Later, in case one of the logged seqs matches the resync request, we return it, together with its record serial number. Before this fix, we mistakenly returned the serial number of the current record instead. Fixes: ed9b764 ("net/tls: Add asynchronous resync") Signed-off-by: Tariq Toukan <[email protected]> Reviewed-by: Boris Pismenny <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent a5bbcbf commit 138559b

File tree

2 files changed

+42
-11
lines changed

2 files changed

+42
-11
lines changed

include/net/tls.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,8 @@ enum tls_offload_sync_type {
300300
#define TLS_DEVICE_RESYNC_ASYNC_LOGMAX 13
301301
struct tls_offload_resync_async {
302302
atomic64_t req;
303-
u32 loglen;
303+
u16 loglen;
304+
u16 rcd_delta;
304305
u32 log[TLS_DEVICE_RESYNC_ASYNC_LOGMAX];
305306
};
306307

@@ -471,6 +472,18 @@ static inline bool tls_bigint_increment(unsigned char *seq, int len)
471472
return (i == -1);
472473
}
473474

475+
static inline void tls_bigint_subtract(unsigned char *seq, int n)
476+
{
477+
u64 rcd_sn;
478+
__be64 *p;
479+
480+
BUILD_BUG_ON(TLS_MAX_REC_SEQ_SIZE != 8);
481+
482+
p = (__be64 *)seq;
483+
rcd_sn = be64_to_cpu(*p);
484+
*p = cpu_to_be64(rcd_sn - n);
485+
}
486+
474487
static inline struct tls_context *tls_get_ctx(const struct sock *sk)
475488
{
476489
struct inet_connection_sock *icsk = inet_csk(sk);
@@ -639,6 +652,7 @@ tls_offload_rx_resync_async_request_start(struct sock *sk, __be32 seq, u16 len)
639652
atomic64_set(&rx_ctx->resync_async->req, ((u64)ntohl(seq) << 32) |
640653
((u64)len << 16) | RESYNC_REQ | RESYNC_REQ_ASYNC);
641654
rx_ctx->resync_async->loglen = 0;
655+
rx_ctx->resync_async->rcd_delta = 0;
642656
}
643657

644658
static inline void

net/tls/tls_device.c

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -694,36 +694,51 @@ static void tls_device_resync_rx(struct tls_context *tls_ctx,
694694

695695
static bool
696696
tls_device_rx_resync_async(struct tls_offload_resync_async *resync_async,
697-
s64 resync_req, u32 *seq)
697+
s64 resync_req, u32 *seq, u16 *rcd_delta)
698698
{
699699
u32 is_async = resync_req & RESYNC_REQ_ASYNC;
700700
u32 req_seq = resync_req >> 32;
701701
u32 req_end = req_seq + ((resync_req >> 16) & 0xffff);
702+
u16 i;
703+
704+
*rcd_delta = 0;
702705

703706
if (is_async) {
707+
/* shouldn't get to wraparound:
708+
* too long in async stage, something bad happened
709+
*/
710+
if (WARN_ON_ONCE(resync_async->rcd_delta == USHRT_MAX))
711+
return false;
712+
704713
/* asynchronous stage: log all headers seq such that
705714
* req_seq <= seq <= end_seq, and wait for real resync request
706715
*/
707-
if (between(*seq, req_seq, req_end) &&
716+
if (before(*seq, req_seq))
717+
return false;
718+
if (!after(*seq, req_end) &&
708719
resync_async->loglen < TLS_DEVICE_RESYNC_ASYNC_LOGMAX)
709720
resync_async->log[resync_async->loglen++] = *seq;
710721

722+
resync_async->rcd_delta++;
723+
711724
return false;
712725
}
713726

714727
/* synchronous stage: check against the logged entries and
715728
* proceed to check the next entries if no match was found
716729
*/
717-
while (resync_async->loglen) {
718-
if (req_seq == resync_async->log[resync_async->loglen - 1] &&
719-
atomic64_try_cmpxchg(&resync_async->req,
720-
&resync_req, 0)) {
721-
resync_async->loglen = 0;
730+
for (i = 0; i < resync_async->loglen; i++)
731+
if (req_seq == resync_async->log[i] &&
732+
atomic64_try_cmpxchg(&resync_async->req, &resync_req, 0)) {
733+
*rcd_delta = resync_async->rcd_delta - i;
722734
*seq = req_seq;
735+
resync_async->loglen = 0;
736+
resync_async->rcd_delta = 0;
723737
return true;
724738
}
725-
resync_async->loglen--;
726-
}
739+
740+
resync_async->loglen = 0;
741+
resync_async->rcd_delta = 0;
727742

728743
if (req_seq == *seq &&
729744
atomic64_try_cmpxchg(&resync_async->req,
@@ -741,6 +756,7 @@ void tls_device_rx_resync_new_rec(struct sock *sk, u32 rcd_len, u32 seq)
741756
u32 sock_data, is_req_pending;
742757
struct tls_prot_info *prot;
743758
s64 resync_req;
759+
u16 rcd_delta;
744760
u32 req_seq;
745761

746762
if (tls_ctx->rx_conf != TLS_HW)
@@ -786,8 +802,9 @@ void tls_device_rx_resync_new_rec(struct sock *sk, u32 rcd_len, u32 seq)
786802
return;
787803

788804
if (!tls_device_rx_resync_async(rx_ctx->resync_async,
789-
resync_req, &seq))
805+
resync_req, &seq, &rcd_delta))
790806
return;
807+
tls_bigint_subtract(rcd_sn, rcd_delta);
791808
break;
792809
}
793810

0 commit comments

Comments
 (0)