]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4034: stream_tcp: accept 1 byte of trimmed probe data after zero window
authorJuweria Ali Imran (jaliimra) <jaliimra@cisco.com>
Thu, 5 Oct 2023 20:28:31 +0000 (20:28 +0000)
committerSteven Baigal (sbaigal) <sbaigal@cisco.com>
Thu, 5 Oct 2023 20:28:31 +0000 (20:28 +0000)
Merge in SNORT/snort3 from ~JALIIMRA/snort3:sfcn_zw_trim to master

Squashed commit of the following:

commit 86635a90a120ba963cee350075bc8f50545f219d
Author: Juweria Ali Imran <jaliimra@cisco.com>
Date:   Thu Sep 28 06:11:46 2023 -0400

    stream_tcp: accept 1 byte of trimmed probe data after zero window

src/stream/tcp/segment_overlap_editor.cc
src/stream/tcp/tcp_defs.h
src/stream/tcp/tcp_normalizer.cc
src/stream/tcp/tcp_normalizer.h
src/stream/tcp/tcp_normalizers.h
src/stream/tcp/tcp_session.cc

index c3cb1da877dba21e0c899e5dbf87d9bdfe3431e5..b95017bf3dedb98b36d9f0826a455ad1f6728a14 100644 (file)
@@ -465,7 +465,7 @@ void SegmentOverlapEditor::full_right_overlap_os5(TcpReassemblerState& trs)
 bool SegmentOverlapEditor::zwp_data_mismatch(
     TcpReassemblerState& trs, TcpSegmentDescriptor& tsd, uint32_t overlap)
 {
-    if ( overlap == ZERO_WIN_PROBE_LEN
+    if ( overlap == MAX_ZERO_WIN_PROBE_LEN
         and trs.sos.right->i_seq == trs.tracker->normalizer.get_zwp_seq()
         and (trs.sos.right->data[0] != tsd.get_pkt()->data[0]) )
     {
index 8b768c64c38464f68cb504fd9fd7a9f37dc2b5d5..7b140e7f55da2fe4e2347a922be64a8212837a71 100644 (file)
@@ -61,7 +61,7 @@ struct Packet;
 
 #define SLAM_MAX 4
 
-#define ZERO_WIN_PROBE_LEN 1
+#define MAX_ZERO_WIN_PROBE_LEN 1
 
 // target-based policy types - changes to this enum require changes to stream.h::TCP_POLICIES
 enum StreamPolicy : uint8_t
index f83d7ebcfa1671104bca7e95b966956b5e0a2b43..275fdb195b3df35e1125c88a014015ed9d49ee80 100644 (file)
@@ -170,8 +170,6 @@ uint32_t TcpNormalizer::get_zwp_seq(
 uint32_t TcpNormalizer::get_stream_window(
     TcpNormalizerState& tns, TcpSegmentDescriptor& tsd)
 {
-    int32_t window;
-
     if ( tns.tracker->get_snd_wnd() )
     {
         if ( !(tns.session->flow->session_state & STREAM_STATE_MIDSTREAM ) )
@@ -181,11 +179,17 @@ uint32_t TcpNormalizer::get_stream_window(
         return tns.tracker->get_snd_wnd();
 
     // ensure the data is in the window
-    window = tsd.get_end_seq() - tns.tracker->r_win_base;
+    return data_inside_window(tns, tsd);
+}
+
+uint32_t TcpNormalizer::data_inside_window(
+    TcpNormalizerState& tns, TcpSegmentDescriptor& tsd)
+{
+    int32_t window = tsd.get_end_seq() - tns.tracker->r_win_base;
     if ( window < 0 )
-        window = 0;
+        return 0;
 
-    return (uint32_t)window;
+    return (uint32_t) window;
 }
 
 uint32_t TcpNormalizer::get_tcp_timestamp(
index d7ccfd7e8bf7f0d79a5f39974e030adcea9b6db2..9a08970183b8fb55733fa227b3cfcae229db5b1d 100644 (file)
@@ -76,6 +76,7 @@ public:
     virtual void ecn_stripper(State&, TcpSegmentDescriptor&);
     virtual uint32_t get_zwp_seq(State&);
     virtual uint32_t get_stream_window(State&, TcpSegmentDescriptor&);
+    virtual uint32_t data_inside_window(State&, TcpSegmentDescriptor&);
     virtual uint32_t get_tcp_timestamp(State&, TcpSegmentDescriptor&, bool strip);
     virtual int handle_paws(State&, TcpSegmentDescriptor&);
     virtual bool validate_rst(State&, TcpSegmentDescriptor&);
index 0a24ce69314997c29b618eac0b0f151cea8d63a2..67befb24218b969e9a537ab5560753bcce36127c 100644 (file)
@@ -80,6 +80,9 @@ public:
     uint32_t get_stream_window(TcpSegmentDescriptor& tsd)
     { return norm->get_stream_window(tns, tsd); }
 
+    uint32_t data_inside_window(TcpSegmentDescriptor& tsd)
+    { return norm->data_inside_window(tns, tsd);  }
+
     uint32_t get_tcp_timestamp(TcpSegmentDescriptor& tsd, bool strip)
     { return norm->get_tcp_timestamp(tns, tsd, strip); }
 
index a021c5c6e8a469941d719312746479edd0c94247..5df70791c48f5e9f9c8e581015b40a947d5572c0 100644 (file)
@@ -475,16 +475,16 @@ int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd)
         if ( tcp_config->policy != StreamPolicy::OS_PROXY
             and listener->normalizer.get_stream_window(tsd) == 0 )
         {
-            if (tsd.get_len() == ZERO_WIN_PROBE_LEN)
+            if ( !listener->normalizer.data_inside_window(tsd) or !listener->get_iss() )
             {
-                tcpStats.zero_win_probes++;
-                listener->normalizer.set_zwp_seq(seq);
+                listener->normalizer.trim_win_payload(tsd);
+                return STREAM_UNALIGNED;
             }
             else
             {
-                bool force = (tsd.is_nap_policy_inline() && listener->get_iss());
-                listener->normalizer.trim_win_payload(tsd, 0, force);
-                return STREAM_UNALIGNED;
+                tcpStats.zero_win_probes++;
+                listener->normalizer.set_zwp_seq(seq);
+                listener->normalizer.trim_win_payload(tsd, MAX_ZERO_WIN_PROBE_LEN, tsd.is_nap_policy_inline());
             }
         }
 
@@ -511,11 +511,14 @@ int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd)
         if ( tcp_config->policy != StreamPolicy::OS_PROXY
             and listener->normalizer.get_stream_window(tsd) == 0 )
         {
-            if (tsd.get_len() == ZERO_WIN_PROBE_LEN)
+            if ( SEQ_EQ(seq, listener->normalizer.get_zwp_seq()) )
+            {
                 tcpStats.zero_win_probes++;
+                listener->normalizer.trim_win_payload(tsd, MAX_ZERO_WIN_PROBE_LEN, tsd.is_nap_policy_inline());
+                return STREAM_UNALIGNED;
+            }
 
-            bool force = (tsd.is_nap_policy_inline() && listener->get_iss());
-            listener->normalizer.trim_win_payload(tsd, 0, force);
+            listener->normalizer.trim_win_payload(tsd);
             return STREAM_UNALIGNED;
         }
         if ( tsd.is_data_segment() )