From 28ff412118644d3014bdcc74bebfa70486ea47c6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Jul 2026 20:26:34 +0000 Subject: [PATCH] sniffer: fix 32-bit sequence number wrap in AdjustSequence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/sniffer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sniffer.c b/src/sniffer.c index a5bdf54d38..0dd6698044 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -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,