]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect-state: handle 'post match' locking
authorVictor Julien <victor@inliniac.net>
Fri, 20 Mar 2015 14:47:39 +0000 (15:47 +0100)
committerVictor Julien <victor@inliniac.net>
Fri, 20 Mar 2015 18:03:48 +0000 (19:03 +0100)
The post match list was called with an unlocked flow until now.
However, recent de_state handling updates changed this. The stateful
detection code can now call the post match functions while keeping
the flow locked. The normal detection code still calls it with an
unlocked flow.

This patch adds a hint to the DetectEngineThreadCtx called
'flow_locked' that is set to true if the caller has already locked
the flow.

src/detect-engine-state.c
src/detect-filestore.c
src/detect-flowvar.c
src/detect-flowvar.h
src/detect.h

index a78a3b62432521a80904272dc80b48f6d39bbdb4..143551be86240534b1d40c82e17b35317e62677a 100644 (file)
@@ -731,7 +731,9 @@ static int DoInspectItem(ThreadVars *tv,
     RULE_PROFILING_END(det_ctx, s, (alert == 1), p);
 
     if (alert) {
+        det_ctx->flow_locked = 1;
         SigMatchSignaturesRunPostMatch(tv, de_ctx, det_ctx, p, s);
+        det_ctx->flow_locked = 0;
 
         if (!(s->flags & SIG_FLAG_NOALERT)) {
             PacketAlertAppend(det_ctx, s, p, inspect_tx_id,
@@ -826,7 +828,9 @@ static int DoInspectFlowRule(ThreadVars *tv,
     item->nm = sm;
 
     if (alert) {
+        det_ctx->flow_locked = 1;
         SigMatchSignaturesRunPostMatch(tv, de_ctx, det_ctx, p, s);
+        det_ctx->flow_locked = 0;
 
         if (!(s->flags & SIG_FLAG_NOALERT)) {
             PacketAlertAppend(det_ctx, s, p, 0,
index 42bb74faf6617ea849c7811c1f364a78ca4122c5..00e8aacc8fd4d7ee4c2626eb1aa6690074af66e7 100644 (file)
@@ -224,7 +224,8 @@ int DetectFilestorePostMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Pack
     else
         flags |= STREAM_TOSERVER;
 
-    FLOWLOCK_WRLOCK(p->flow);
+    if (det_ctx->flow_locked == 0)
+        FLOWLOCK_WRLOCK(p->flow);
 
     FileContainer *ffc = AppLayerParserGetFiles(p->flow->proto, p->flow->alproto,
                                                 p->flow->alstate, flags);
@@ -245,7 +246,9 @@ int DetectFilestorePostMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Pack
         }
     }
 
-    FLOWLOCK_UNLOCK(p->flow);
+    if (det_ctx->flow_locked == 0)
+        FLOWLOCK_UNLOCK(p->flow);
+
     SCReturnInt(0);
 }
 
index 0746393e637c6ad2eac67197788fbbfb4616a02a..8e8fddee0be1b2f67d910a5f25fb5f9c289c3719 100644 (file)
@@ -288,6 +288,7 @@ static int DetectFlowvarPostMatch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx
 {
     DetectFlowvarList *fs, *prev;
     const DetectFlowvarData *fd;
+    const int flow_locked = det_ctx->flow_locked;
 
     if (det_ctx->flowvarlist == NULL || p->flow == NULL)
         return 1;
@@ -301,7 +302,10 @@ static int DetectFlowvarPostMatch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx
             SCLogDebug("adding to the flow %u:", fs->idx);
             //PrintRawDataFp(stdout, fs->buffer, fs->len);
 
-            FlowVarAddStr(p->flow, fs->idx, fs->buffer, fs->len);
+            if (flow_locked)
+                FlowVarAddStrNoLock(p->flow, fs->idx, fs->buffer, fs->len);
+            else
+                FlowVarAddStr(p->flow, fs->idx, fs->buffer, fs->len);
             /* memory at fs->buffer is now the responsibility of
              * the flowvar code. */
 
@@ -327,7 +331,7 @@ static int DetectFlowvarPostMatch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx
  *         - enforce storage for type ALWAYS (luajit)
  *   Only called from DetectFlowvarProcessList() when flowvarlist is not NULL .
  */
-void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f)
+void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f, const int flow_locked)
 {
     DetectFlowvarList *next;
 
@@ -339,7 +343,10 @@ void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f)
             SCLogDebug("adding to the flow %u:", fs->idx);
             //PrintRawDataFp(stdout, fs->buffer, fs->len);
 
-            FlowVarAddStr(f, fs->idx, fs->buffer, fs->len);
+            if (flow_locked)
+                FlowVarAddStrNoLock(f, fs->idx, fs->buffer, fs->len);
+            else
+                FlowVarAddStr(f, fs->idx, fs->buffer, fs->len);
             /* memory at fs->buffer is now the responsibility of
              * the flowvar code. */
         } else
index 7ee12f02ccd7c653dd9b898cfd75c9c5444f67c9..9e72a5bcb5c44669c313182e14f2928b39ff11ce 100644 (file)
@@ -39,16 +39,17 @@ int DetectFlowvarPostMatchSetup(Signature *s, uint16_t idx);
 int DetectFlowvarStoreMatch(DetectEngineThreadCtx *, uint16_t, uint8_t *, uint16_t, int);
 
 /* For use only by DetectFlowvarProcessList() */
-void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f);
+void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f, const int flow_locked);
 static inline void DetectFlowvarProcessList(DetectEngineThreadCtx *det_ctx, Flow *f)
 {
     DetectFlowvarList *fs = det_ctx->flowvarlist;
+    const int flow_locked = det_ctx->flow_locked;
 
     SCLogDebug("det_ctx->flowvarlist %p", fs);
 
     if (fs != NULL) {
         det_ctx->flowvarlist = NULL;
-        DetectFlowvarProcessListInternal(fs, f);
+        DetectFlowvarProcessListInternal(fs, f, flow_locked);
     }
 }
 
index 973f7f87cf50c8475dab4f2fdb87c7277527c7ea..80d6d6a97d2c8578dc1215a2da80aa4518d00496 100644 (file)
@@ -774,7 +774,7 @@ typedef struct HttpReassembledBody_ {
 /**
   * Detection engine thread data.
   */
-typedef struct DetectionEngineThreadCtx_ {
+typedef struct DetectEngineThreadCtx_ {
     /* the thread to which this detection engine thread belongs */
     ThreadVars *tv;
 
@@ -792,6 +792,10 @@ typedef struct DetectionEngineThreadCtx_ {
     /* counter for the filestore array below -- up here for cache reasons. */
     uint16_t filestore_cnt;
 
+    /* bool to hint the POSTMATCH list members about the lock status of the
+     * flow. If locked this is TRUE, unlocked or no-flow: FALSE */
+    uint8_t flow_locked;
+
     HttpReassembledBody *hsbd;
     uint64_t hsbd_start_tx_id;
     uint16_t hsbd_buffers_size;