From 92dae7365733dde0ff594cb203633cb321426855 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Tue, 2 Dec 2025 10:14:12 +0100 Subject: [PATCH] stream/tcp: check new last_ack stays within base_seq bounds If we have - stream->last_ack 0x40021 Then, we call StreamTcpUpdateLastAck with 0x8000fc21 Then we satisfy SEQ_GT((ack), (stream)->last_ack) But we do not satisfy SEQ_GT(ack, (stream)->base_seq)) and the new last_ack will be compared to base_seq So, refuse to make such a big update Ticket: 6865 (cherry picked from commit 09e50ac3f4295fa9e1978356352b03a5a2062900) --- src/stream-tcp.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/stream-tcp.c b/src/stream-tcp.c index ea752e7f41..adc6b9f93b 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -1065,22 +1065,26 @@ void StreamTcpSetOSPolicy(TcpStream *stream, Packet *p) * \param stream stream to update * \param ack ACK value to test and set */ -#define StreamTcpUpdateLastAck(ssn, stream, ack) { \ - if (SEQ_GT((ack), (stream)->last_ack)) \ - { \ - SCLogDebug("ssn %p: last_ack set to %"PRIu32", moved %u forward", (ssn), (ack), (ack) - (stream)->last_ack); \ - if ((SEQ_LEQ((stream)->last_ack, (stream)->next_seq) && SEQ_GT((ack),(stream)->next_seq))) { \ - SCLogDebug("last_ack just passed next_seq: %u (was %u) > %u", (ack), (stream)->last_ack, (stream)->next_seq); \ - } else { \ - SCLogDebug("next_seq (%u) <> last_ack now %d", (stream)->next_seq, (int)(stream)->next_seq - (ack)); \ - }\ - (stream)->last_ack = (ack); \ - StreamTcpSackPruneList((stream)); \ - } else { \ - SCLogDebug("ssn %p: no update: ack %u, last_ack %"PRIu32", next_seq %u (state %u)", \ - (ssn), (ack), (stream)->last_ack, (stream)->next_seq, (ssn)->state); \ - }\ -} +#define StreamTcpUpdateLastAck(ssn, stream, ack) \ + { \ + if (SEQ_GT((ack), (stream)->last_ack) && SEQ_GT(ack, (stream)->base_seq)) { \ + SCLogDebug("ssn %p: last_ack set to %" PRIu32 ", moved %u forward", (ssn), (ack), \ + (ack) - (stream)->last_ack); \ + if ((SEQ_LEQ((stream)->last_ack, (stream)->next_seq) && \ + SEQ_GT((ack), (stream)->next_seq))) { \ + SCLogDebug("last_ack just passed next_seq: %u (was %u) > %u", (ack), \ + (stream)->last_ack, (stream)->next_seq); \ + } else { \ + SCLogDebug("next_seq (%u) <> last_ack now %d", (stream)->next_seq, \ + (int)(stream)->next_seq - (ack)); \ + } \ + (stream)->last_ack = (ack); \ + StreamTcpSackPruneList((stream)); \ + } else { \ + SCLogDebug("ssn %p: no update: ack %u, last_ack %" PRIu32 ", next_seq %u (state %u)", \ + (ssn), (ack), (stream)->last_ack, (stream)->next_seq, (ssn)->state); \ + } \ + } #define StreamTcpAsyncLastAckUpdate(ssn, stream) { \ if ((ssn)->flags & STREAMTCP_FLAG_ASYNC) { \