From: Russ Combs (rucombs) Date: Wed, 1 Feb 2017 17:38:04 +0000 (-0500) Subject: Merge pull request #797 in SNORT/snort3 from stream_flush_segfault_fix to master X-Git-Tag: 3.0.0-233~89 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3ff2e8e16a2ddac7ace348367f97bf2107e084fd;p=thirdparty%2Fsnort3.git Merge pull request #797 in SNORT/snort3 from stream_flush_segfault_fix to master Squashed commit of the following: commit 52c88a06bef55c02102ed234ec8b69bb7ac9d9eb Author: davis mcpherson Date: Tue Jan 31 17:52:14 2017 -0500 check that the tracker splitter object is valid before trying to call the splitter finish method when doing the final flush on a flow --- diff --git a/src/stream/tcp/tcp_session.cc b/src/stream/tcp/tcp_session.cc index fa95c02ba..06c9caef3 100644 --- a/src/stream/tcp/tcp_session.cc +++ b/src/stream/tcp/tcp_session.cc @@ -870,68 +870,36 @@ void TcpSession::flush_client(Packet* p) client->clear_tf_flags(TF_FORCE_FLUSH); } -void TcpSession::flush_listener(Packet* p, bool final_flush) +void TcpSession::flush_tracker(TcpStreamTracker* tracker, Packet* p, uint32_t dir, bool final_flush) { - TcpStreamTracker* listener = nullptr; - uint32_t dir = 0; + if( final_flush && ( !tracker->splitter || !tracker->splitter->finish(flow) ) ) + return; + + DebugFormat(DEBUG_STREAM_STATE, "Flushing tracker on packet from %s\n", + (dir == PKT_FROM_CLIENT) ? "client" : "server"); + tracker->set_tf_flags(TF_FORCE_FLUSH); + if ( tracker->reassembler->flush_stream(p, dir) ) + tracker->reassembler->purge_flushed_ackd( ); + + tracker->clear_tf_flags(TF_FORCE_FLUSH); +} +void TcpSession::flush_listener(Packet* p, bool final_flush) +{ // direction of flush is the data from the opposite side if ( p->is_from_server() ) - { - listener = client; - dir = PKT_FROM_SERVER; - } + flush_tracker( client, p, PKT_FROM_SERVER, final_flush); else if ( p->is_from_client() ) - { - listener = server; - dir = PKT_FROM_CLIENT; - } - - if ( dir ) - { - if( final_flush && !listener->splitter->finish(flow) ) - return; - - DebugFormat(DEBUG_STREAM_STATE, "Flushing listener on packet from %s\n", - (dir == PKT_FROM_CLIENT) ? "client" : "server"); - listener->set_tf_flags(TF_FORCE_FLUSH); - if ( listener->reassembler->flush_stream(p, dir) ) - listener->reassembler->purge_flushed_ackd( ); - - listener->clear_tf_flags(TF_FORCE_FLUSH); - } + flush_tracker( server, p, PKT_FROM_CLIENT, final_flush); } void TcpSession::flush_talker(Packet* p, bool final_flush) { - TcpStreamTracker* talker = nullptr; - uint32_t dir = 0; - - /* direction of flush is the data from the opposite side */ + // direction of flush is the data from the opposite side if ( p->is_from_server() ) - { - talker = server; - dir = PKT_FROM_CLIENT; - } + flush_tracker( server, p, PKT_FROM_CLIENT, final_flush); else if ( p->is_from_client() ) - { - talker = client; - dir = PKT_FROM_SERVER; - } - - if ( dir ) - { - if( final_flush && !talker->splitter->finish(flow) ) - return; - - DebugFormat(DEBUG_STREAM_STATE, "Flushing talker on packet from %s\n", - (dir == PKT_FROM_SERVER) ? "client" : "server"); - talker->set_tf_flags(TF_FORCE_FLUSH); - if ( talker->reassembler->flush_stream(p, dir) ) - talker->reassembler->purge_flushed_ackd( ); - - talker->clear_tf_flags(TF_FORCE_FLUSH); - } + flush_tracker( client, p, PKT_FROM_SERVER, final_flush); } void TcpSession::set_extra_data(Packet* p, uint32_t xid) diff --git a/src/stream/tcp/tcp_session.h b/src/stream/tcp/tcp_session.h index b479c1a2d..16cbf17c6 100644 --- a/src/stream/tcp/tcp_session.h +++ b/src/stream/tcp/tcp_session.h @@ -81,6 +81,7 @@ private: void cleanup_session_if_expired(Packet*); bool do_packet_analysis_pre_checks(Packet*, TcpSegmentDescriptor&); void do_packet_analysis_post_checks(Packet*); + void flush_tracker(TcpStreamTracker*, Packet*, uint32_t dir, bool final_flush); TcpStateMachine* tsm; };