From: Juweria Ali Imran (jaliimra) Date: Fri, 14 Jul 2023 13:12:24 +0000 (+0000) Subject: Pull request #3906: stream_tcp: update state appropriately when head of seglist is... X-Git-Tag: 3.1.66.0~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee58a55a989c15dddb218dbb7e30ef989a27e4dc;p=thirdparty%2Fsnort3.git Pull request #3906: stream_tcp: update state appropriately when head of seglist is the right end of a hole Merge in SNORT/snort3 from ~JALIIMRA/snort3:seglist_hole_infinite_recursion to master Squashed commit of the following: commit d33b0d33a920dfa8331b487a4c666b7f79c10314 Author: Juweria Ali Imran Date: Tue Jun 20 13:02:14 2023 -0400 stream_tcp: validate proper update of stream_tcp state when seglist head follows a hole --- diff --git a/src/stream/tcp/tcp_reassembler.cc b/src/stream/tcp/tcp_reassembler.cc index 9f516fcb0..7d981e490 100644 --- a/src/stream/tcp/tcp_reassembler.cc +++ b/src/stream/tcp/tcp_reassembler.cc @@ -972,12 +972,26 @@ void TcpReassembler::fallback(TcpStreamTracker& tracker, bool server_side) } } +void TcpReassembler::check_first_segment_hole(TcpReassemblerState& trs) +{ + if ( SEQ_LT(trs.sos.seglist_base_seq, trs.sos.seglist.head->c_seq) + and SEQ_EQ(trs.sos.seglist_base_seq, trs.tracker->rcv_nxt) ) + { + trs.sos.seglist_base_seq = trs.sos.seglist.head->c_seq; + trs.tracker->rcv_nxt = trs.tracker->r_win_base; + trs.paf_state.paf = StreamSplitter::START; + } +} + bool TcpReassembler::has_seglist_hole(TcpReassemblerState& trs, TcpSegmentNode& tsn, PAF_State& ps, uint32_t& total, uint32_t& flags) { if ( !tsn.prev or SEQ_GEQ(tsn.prev->c_seq + tsn.prev->c_len, tsn.c_seq) or SEQ_GEQ(tsn.c_seq, trs.tracker->r_win_base) ) - return false; + { + check_first_segment_hole(trs); + return false; + } // safety - prevent seq + total < seq if ( total > 0x7FFFFFFF ) diff --git a/src/stream/tcp/tcp_reassembler.h b/src/stream/tcp/tcp_reassembler.h index e5c86097d..b83f28d2c 100644 --- a/src/stream/tcp/tcp_reassembler.h +++ b/src/stream/tcp/tcp_reassembler.h @@ -99,6 +99,7 @@ protected: bool fin_acked_no_gap(const TcpSegmentNode&, const TcpReassemblerState&); void update_next(TcpReassemblerState&, const TcpSegmentNode&); void update_skipped_bytes(uint32_t, TcpReassemblerState&); + void check_first_segment_hole(TcpReassemblerState&); bool has_seglist_hole(TcpReassemblerState&, TcpSegmentNode&, PAF_State&, uint32_t& total, uint32_t& flags); void skip_seglist_hole(TcpReassemblerState&, snort::Packet*, uint32_t flags,