]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream: handle no stream scanning case
authorVictor Julien <victor@inliniac.net>
Wed, 22 Feb 2017 10:14:02 +0000 (11:14 +0100)
committerVictor Julien <victor@inliniac.net>
Thu, 20 Apr 2017 15:41:11 +0000 (17:41 +0200)
Now that detect moves the raw progress forward, it's important
to deal with the case where detect don't consider raw inspection.

If no 'stream' rules are active, disable raw. For this the disable
raw flag is now per stream.

src/detect-engine-mpm.c
src/detect.c
src/detect.h
src/stream-tcp-list.c
src/stream-tcp-private.h
src/stream-tcp-reassemble.c
src/stream-tcp.c
src/stream-tcp.h

index 40ec280f8e7965e6f0e5b1cbf9cd223a4fb96dac..bd7dbc40f335e4acb51b658c983c604ddbc5752a 100644 (file)
@@ -1194,6 +1194,25 @@ static MpmStore *MpmStorePrepareBufferAppLayer(DetectEngineCtx *de_ctx,
     return NULL;
 }
 
+static void SetRawReassemblyFlag(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
+{
+    const Signature *s = NULL;
+    uint32_t sig;
+
+    for (sig = 0; sig < sgh->sig_cnt; sig++) {
+        s = sgh->match_array[sig];
+        if (s == NULL)
+            continue;
+
+        if (SignatureHasStreamContent(s) == 1) {
+            sgh->flags |= SIG_GROUP_HEAD_HAVERAWSTREAM;
+            SCLogDebug("rule group %p has SIG_GROUP_HEAD_HAVERAWSTREAM set", sgh);
+            return;
+        }
+    }
+    SCLogDebug("rule group %p does NOT have SIG_GROUP_HEAD_HAVERAWSTREAM set", sgh);
+}
+
 /** \brief Prepare the pattern matcher ctx in a sig group head.
  *
  */
@@ -1211,6 +1230,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
             if (mpm_store != NULL) {
                 PrefilterPktStreamRegister(sh, mpm_store->mpm_ctx);
             }
+
+            SetRawReassemblyFlag(de_ctx, sh);
         }
         if (SGH_DIRECTION_TC(sh)) {
             mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_TCP_PKT_TC);
@@ -1222,6 +1243,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
             if (mpm_store != NULL) {
                 PrefilterPktStreamRegister(sh, mpm_store->mpm_ctx);
             }
+
+            SetRawReassemblyFlag(de_ctx, sh);
        }
     } else if (SGH_PROTO(sh, IPPROTO_UDP)) {
         if (SGH_DIRECTION_TS(sh)) {
index ca6cdb385d8c0c3a2c9e513d50060ad4a4b76ffc..ae8d803f53e72e343763d2f3a4ee5fd7bf0e148c 100644 (file)
@@ -860,6 +860,14 @@ DetectPostInspectFirstSGH(const Packet *p, Flow *pflow, const SigGroupHead *sgh)
         pflow->sgh_toserver = sgh;
         pflow->flags |= FLOW_SGH_TOSERVER;
 
+        if (p->proto == IPPROTO_TCP && (sgh == NULL || !(sgh->flags & SIG_GROUP_HEAD_HAVERAWSTREAM))) {
+            if (pflow->protoctx != NULL) {
+                TcpSession *ssn = pflow->protoctx;
+                SCLogDebug("STREAMTCP_STREAM_FLAG_DISABLE_RAW ssn.client");
+                ssn->client.flags |= STREAMTCP_STREAM_FLAG_DISABLE_RAW;
+            }
+        }
+
         DetectPostInspectFileFlagsUpdate(pflow,
                 pflow->sgh_toserver, STREAM_TOSERVER);
 
@@ -867,6 +875,14 @@ DetectPostInspectFirstSGH(const Packet *p, Flow *pflow, const SigGroupHead *sgh)
         pflow->sgh_toclient = sgh;
         pflow->flags |= FLOW_SGH_TOCLIENT;
 
+        if (p->proto == IPPROTO_TCP && (sgh == NULL || !(sgh->flags & SIG_GROUP_HEAD_HAVERAWSTREAM))) {
+            if (pflow->protoctx != NULL) {
+                TcpSession *ssn = pflow->protoctx;
+                SCLogDebug("STREAMTCP_STREAM_FLAG_DISABLE_RAW ssn.server");
+                ssn->server.flags |= STREAMTCP_STREAM_FLAG_DISABLE_RAW;
+            }
+        }
+
         DetectPostInspectFileFlagsUpdate(pflow,
                 pflow->sgh_toclient, STREAM_TOCLIENT);
     }
@@ -1276,8 +1292,10 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
                 }
                 /* no match? then inspect packet payload */
                 if (pmatch == 0) {
-                    SCLogDebug("no match in smsg, fall back to packet payload");
+                    SCLogDebug("no match in stream, fall back to packet payload");
 
+                    /* skip if we don't have to inspect the packet and segment was
+                     * added to stream */
                     if (!(sflags & SIG_FLAG_REQUIRE_PACKET) && (p->flags & PKT_STREAM_ADD)) {
                         goto next;
                     }
index 1a3286d66ee5231e48ca9db4c2ddcb0f5962bd96..d9bf453b4dfa7f6303dee964d12f0e8b5574375c 100644 (file)
@@ -946,6 +946,7 @@ typedef struct SigTableElmt_ {
 
 } SigTableElmt;
 
+#define SIG_GROUP_HEAD_HAVERAWSTREAM    (1 << 0)
 #ifdef HAVE_MAGIC
 #define SIG_GROUP_HEAD_HAVEFILEMAGIC    (1 << 20)
 #endif
index 07a87a48b41ee88efd0ec3394646d9b538153d1d..0944045b8df568db2b0a51097639622f8526966c 100644 (file)
@@ -628,7 +628,7 @@ static inline uint64_t GetLeftEdge(TcpSession *ssn, TcpStream *stream)
         use_app = 0;
     }
 
-    if (ssn->flags & STREAMTCP_FLAG_DISABLE_RAW) {
+    if (stream->flags & STREAMTCP_STREAM_FLAG_DISABLE_RAW) {
         // raw is dead
         use_raw = 0;
     }
index 9569be4edb7626abc7a0028d92d850ca4947b2f1..dcc7693c4c1d9a3b64d934cb063e7ade18f672fa 100644 (file)
@@ -134,8 +134,7 @@ enum
 #define STREAMTCP_FLAG_TIMESTAMP                    0x0008
 /** Server supports wscale (even though it can be 0) */
 #define STREAMTCP_FLAG_SERVER_WSCALE                0x0010
-/** 'Raw' reassembly is disabled for this ssn. */
-#define STREAMTCP_FLAG_DISABLE_RAW                  0x0020
+// vacancy
 /** Flag to indicate that the session is handling asynchronous stream.*/
 #define STREAMTCP_FLAG_ASYNC                        0x0040
 /** Flag to indicate we're dealing with 4WHS: SYN, SYN, SYN/ACK, ACK
@@ -148,9 +147,7 @@ enum
 #define STREAMTCP_FLAG_CLIENT_SACKOK                0x0200
 /** Flag to indicate both sides of the session permit SACK (SYN + SYN/ACK) */
 #define STREAMTCP_FLAG_SACKOK                       0x0400
-/** Flag for triggering RAW reassembly before the size limit is reached or
-    the stream reaches EOF. */
-//#define STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY       0x0800
+// vacancy
 /** 3WHS confirmed by server -- if suri sees 3whs ACK but server doesn't (pkt
  *  is lost on the way to server), SYN/ACK is retransmitted. If server sends
  *  normal packet we assume 3whs to be completed. Only used for SYN/ACK resend
@@ -184,7 +181,10 @@ enum
 #define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_SKIPPED 0x0100
 /** Raw reassembly disabled for new segments */
 #define STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED 0x0200
-// vacancy 2x
+/** Raw reassembly disabled completely */
+#define STREAMTCP_STREAM_FLAG_DISABLE_RAW 0x400
+// vacancy 1x
+
 /** NOTE: flags field is 12 bits */
 
 
index 2957d3977979ea12ecb3fbbf44975e711a51125b..3586e3cfc8f6e52f16aec6396d06ac7b2ae18d11 100644 (file)
@@ -794,7 +794,7 @@ int StreamNeedsReassembly(TcpSession *ssn, int direction)
         use_app = 0;
     }
 
-    if (ssn->flags & STREAMTCP_FLAG_DISABLE_RAW) {
+    if (stream->flags & STREAMTCP_STREAM_FLAG_DISABLE_RAW) {
         // raw is dead
         use_raw = 0;
     }
index 120fa2369d26ec53ba1e36d619dc2c1413469e74..5ecb702c0f2663e7abd670cecedaefa11b8a9ec0 100644 (file)
@@ -560,7 +560,7 @@ void StreamTcpInitConfig(char quiet)
     int enable_raw = 1;
     if (ConfGetBool("stream.reassembly.raw", &enable_raw) == 1) {
         if (!enable_raw) {
-            stream_config.ssn_init_flags = STREAMTCP_FLAG_DISABLE_RAW;
+            stream_config.stream_init_flags = STREAMTCP_STREAM_FLAG_DISABLE_RAW;
         }
     } else {
         enable_raw = 1;
@@ -639,8 +639,9 @@ TcpSession *StreamTcpNewSession (Packet *p, int id)
 
         ssn->state = TCP_NONE;
         ssn->reassembly_depth = stream_config.reassembly_depth;
-        ssn->flags = stream_config.ssn_init_flags;
         ssn->tcp_packet_flags = p->tcph ? p->tcph->th_flags : 0;
+        ssn->server.flags = stream_config.stream_init_flags;
+        ssn->client.flags = stream_config.stream_init_flags;
 
         StreamingBuffer x = STREAMING_BUFFER_INITIALIZER(&stream_config.sbcnf);
         ssn->client.sb = x;
index d4dcf183f039245c68afe65dfd114325d849732c..11db4a0c827738b2008fbd59ad2720db8113e01d 100644 (file)
@@ -44,7 +44,7 @@ typedef struct TcpStreamCnf_ {
     uint64_t memcap;
     uint64_t reassembly_memcap; /**< max memory usage for stream reassembly */
 
-    uint32_t ssn_init_flags; /**< new ssn flags will be initialized to this */
+    uint16_t stream_init_flags; /**< new stream flags will be initialized to this */
 
     uint32_t prealloc_sessions; /**< ssns to prealloc per stream thread */
     uint32_t prealloc_segments; /**< segments to prealloc per stream thread */