sniffer: fix 32-bit sequence number wrap in AdjustSequence

Plain unsigned comparisons (real < *expected, real > *expected) give
the wrong result when the relative sequence number wraps past 2^32 (i.e.
after ~4 GB of session data).  For example, if expected=0xFFFFFFF8 and
the next segment's real=0x00000000 (after wrap), the old code enters the
"already seen / duplicate" branch and discards the segment.

Replace every affected comparison with signed 32-bit (RFC 1982) serial-
number arithmetic: (sword32)(a - b) < 0  ↔  a is before b, even across
the 32-bit boundary.  This is the same technique used throughout the
Linux kernel TCP stack and is well-defined for unsigned wrapping.
copilot/confirm-sequence-comparison-issue
copilot-swe-agent[bot] 2026-07-23 20:26:34 +00:00 committed by GitHub
parent 7dcc3dee29
commit 28ff412118
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 6 additions and 6 deletions

View File

@ -5818,10 +5818,10 @@ static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session,
TraceRelativeSequence(*expected, real);
if (real < *expected) {
int overlap = *expected - real;
if ((sword32)(real - *expected) < 0) {
int overlap = (int)(*expected - real);
if (real + *sslBytes > *expected) {
if ((sword32)((real + (word32)*sslBytes) - *expected) > 0) {
#ifdef WOLFSSL_ASYNC_CRYPT
if (session->sslServer->error != WC_NO_ERR_TRACE(WC_PENDING_E) &&
session->pendSeq != tcpInfo->sequence)
@ -5863,7 +5863,7 @@ static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session,
}
}
else if (*sslBytes > 0) {
if (real + *sslBytes - 1 > *seqLast) {
if ((sword32)((real + (word32)*sslBytes - 1) - *seqLast) > 0) {
/* fix segment overlap */
#ifdef DEBUG_SNIFFER
WOLFSSL* ssl = (session->flags.side == WOLFSSL_SERVER_END) ?
@ -5893,7 +5893,7 @@ static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session,
session->sslServer->error != WC_NO_ERR_TRACE(WC_PENDING_E) &&
session->pendSeq != tcpInfo->sequence &&
#endif
real + *sslBytes -1 <= *seqLast) {
(sword32)((real + (word32)*sslBytes - 1) - *seqLast) <= 0) {
Trace(DUPLICATE_STR);
ret = 1;
}
@ -5909,7 +5909,7 @@ static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session,
}
}
}
else if (real > *expected) {
else if ((sword32)(real - *expected) > 0) {
Trace(OUT_OF_ORDER_STR);
if (*sslBytes > 0) {
int addResult = AddToReassembly(session->flags.side, real,