]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
pkt-var: abuse flowvar postmatch logic for pktvars
authorVictor Julien <victor@inliniac.net>
Thu, 27 Oct 2016 15:41:38 +0000 (17:41 +0200)
committerVictor Julien <victor@inliniac.net>
Thu, 16 Feb 2017 09:35:44 +0000 (10:35 +0100)
Flowvars were already using a temporary store in the detect thread
ctx.

Use the same facility for pktvars. The reasons are:

1. packet is not always available, e.g. when running pcre on http
   buffers.

2. setting of vars should be done post match. Until now it was also
   possible that it is done on a partial match.

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

index e25accf3fd0acd5ef52c2e0ee1a22136de388099..687e3b397ba698f859aebf66ff04b694f1ccd98a 100644 (file)
@@ -715,7 +715,7 @@ static int DoInspectItem(ThreadVars *tv,
         SCLogDebug("MATCH: tx %u packet %u", (uint)inspect_tx_id, (uint)p->pcap_cnt);
     }
 
-    DetectFlowvarProcessList(det_ctx, f);
+    DetectVarProcessList(det_ctx, f, p);
     return 1;
 }
 
index c5f838bb6c31242565ae56323283c45a92d1da7f..b0c30d4099b08a99cc78ea22278214d2000b608f 100644 (file)
@@ -33,6 +33,7 @@
 #include "threads.h"
 #include "flow.h"
 #include "flow-var.h"
+#include "pkt-var.h"
 #include "detect-flowvar.h"
 
 #include "util-spm.h"
@@ -194,10 +195,10 @@ error:
 
 
 /** \brief Store flowvar in det_ctx so we can exec it post-match */
-int DetectFlowvarStoreMatch(DetectEngineThreadCtx *det_ctx, uint32_t idx,
+int DetectVarStoreMatch(DetectEngineThreadCtx *det_ctx, uint32_t idx,
         uint8_t *buffer, uint16_t len, int type)
 {
-    DetectFlowvarList *fs = det_ctx->flowvarlist;
+    DetectVarList *fs = det_ctx->varlist;
 
     /* first check if we have had a previous match for this idx */
     for ( ; fs != NULL; fs = fs->next) {
@@ -216,8 +217,8 @@ int DetectFlowvarStoreMatch(DetectEngineThreadCtx *det_ctx, uint32_t idx,
 
         fs->idx = idx;
 
-        fs->next = det_ctx->flowvarlist;
-        det_ctx->flowvarlist = fs;
+        fs->next = det_ctx->varlist;
+        det_ctx->varlist = fs;
     }
 
     fs->len = len;
@@ -266,29 +267,33 @@ static int DetectFlowvarPostMatch(ThreadVars *tv,
         DetectEngineThreadCtx *det_ctx,
         Packet *p, const Signature *s, const SigMatchCtx *ctx)
 {
-    DetectFlowvarList *fs, *prev;
+    DetectVarList *fs, *prev;
     const DetectFlowvarData *fd;
 
-    if (det_ctx->flowvarlist == NULL || p->flow == NULL)
+    if (det_ctx->varlist == NULL)
         return 1;
 
     fd = (const DetectFlowvarData *)ctx;
 
     prev = NULL;
-    fs = det_ctx->flowvarlist;
+    fs = det_ctx->varlist;
     while (fs != NULL) {
         if (fd->idx == fs->idx) {
             SCLogDebug("adding to the flow %u:", fs->idx);
             //PrintRawDataFp(stdout, fs->buffer, fs->len);
 
-            FlowVarAddStrNoLock(p->flow, fs->idx, fs->buffer, fs->len);
-            /* memory at fs->buffer is now the responsibility of
-             * the flowvar code. */
+            if (fs->type == DETECT_VAR_TYPE_FLOW_POSTMATCH && p && p->flow) {
+                FlowVarAddStrNoLock(p->flow, fs->idx, fs->buffer, fs->len);
+                /* memory at fs->buffer is now the responsibility of
+                 * the flowvar code. */
+            } else if (fs->type == DETECT_VAR_TYPE_PKT_POSTMATCH && p) {
+                PktVarAdd(p, fs->idx, fs->buffer, fs->len);
+            }
 
-            if (fs == det_ctx->flowvarlist) {
-                det_ctx->flowvarlist = fs->next;
+            if (fs == det_ctx->varlist) {
+                det_ctx->varlist = fs->next;
                 SCFree(fs);
-                fs = det_ctx->flowvarlist;
+                fs = det_ctx->varlist;
             } else {
                 prev->next = fs->next;
                 SCFree(fs);
@@ -307,14 +312,14 @@ static int DetectFlowvarPostMatch(ThreadVars *tv,
  *         - enforce storage for type ALWAYS (vars set from lua)
  *   Only called from DetectFlowvarProcessList() when flowvarlist is not NULL .
  */
-void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f)
+void DetectVarProcessListInternal(DetectVarList *fs, Flow *f, Packet *p)
 {
-    DetectFlowvarList *next;
+    DetectVarList *next;
 
     do {
         next = fs->next;
 
-        if (fs->type == DETECT_FLOWVAR_TYPE_ALWAYS) {
+        if (fs->type == DETECT_VAR_TYPE_ALWAYS) {
             SCLogDebug("adding to the flow %u:", fs->idx);
             //PrintRawDataFp(stdout, fs->buffer, fs->len);
 
index 32222372b4bf9f075f07545c625be745acc0dbc7..59edfc80bc175a0082ccf485a009b2d9d4ec9649 100644 (file)
@@ -36,18 +36,18 @@ typedef struct DetectFlowvarData_ {
 void DetectFlowvarRegister (void);
 
 int DetectFlowvarPostMatchSetup(Signature *s, uint32_t idx);
-int DetectFlowvarStoreMatch(DetectEngineThreadCtx *, uint32_t, uint8_t *, uint16_t, int);
+int DetectVarStoreMatch(DetectEngineThreadCtx *, uint32_t, uint8_t *, uint16_t, int);
 
 /* For use only by DetectFlowvarProcessList() */
-void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f);
-static inline void DetectFlowvarProcessList(DetectEngineThreadCtx *det_ctx, Flow *f)
+void DetectVarProcessListInternal(DetectVarList *fs, Flow *f, Packet *p);
+static inline void DetectVarProcessList(DetectEngineThreadCtx *det_ctx, Flow *f, Packet *p)
 {
-    DetectFlowvarList *fs = det_ctx->flowvarlist;
+    DetectVarList *fs = det_ctx->varlist;
 
-    SCLogDebug("flow %p det_ctx->flowvarlist %p", f, fs);
-    if (f && fs != NULL) {
-        det_ctx->flowvarlist = NULL;
-        DetectFlowvarProcessListInternal(fs, f);
+    SCLogDebug("flow %p det_ctx->varlist %p", f, fs);
+    if ((f || p) && fs != NULL) {
+        det_ctx->varlist = NULL;
+        DetectVarProcessListInternal(fs, f, p);
     }
 }
 
index 1fe8af27584d8c93c752dae8dd75bfa1b8dbcd27..0d0a46756e3f3ef645b4b629c33a99771b663f0d 100644 (file)
@@ -219,21 +219,28 @@ int DetectPcrePayloadMatch(DetectEngineThreadCtx *det_ctx, const Signature *s,
             if (ret > 1 && pe->idx != 0) {
                 uint8_t x;
                 for (x = 0; x < pe->idx; x++) {
-                    SCLogDebug("capturing");
+                    SCLogDebug("capturing %u", x);
                     const char *str_ptr;
                     ret = pcre_get_substring((char *)ptr, ov, MAX_SUBSTRINGS, x+1, &str_ptr);
                     if (unlikely(ret == 0))
                         continue;
 
-                    if (pe->captypes[x] == VAR_TYPE_PKT_VAR && p != NULL) {
-                        PktVarAdd(p, pe->capids[x], (uint8_t *)str_ptr, ret);
+                    SCLogDebug("data %p/%u, type %u id %u p %p",
+                            str_ptr, ret, pe->captypes[x], pe->capids[x], p);
+
+                    if (pe->captypes[x] == VAR_TYPE_PKT_VAR) {
+                        /* store max 64k. Errors are ignored */
+                        capture_len = (ret < 0xffff) ? (uint16_t)ret : 0xffff;
+                        (void)DetectVarStoreMatch(det_ctx, pe->capids[x],
+                                (uint8_t *)str_ptr, capture_len,
+                                DETECT_VAR_TYPE_PKT_POSTMATCH);
 
                     } else if (pe->captypes[x] == VAR_TYPE_FLOW_VAR && f != NULL) {
                         /* store max 64k. Errors are ignored */
                         capture_len = (ret < 0xffff) ? (uint16_t)ret : 0xffff;
-                        (void)DetectFlowvarStoreMatch(det_ctx, pe->capids[x],
+                        (void)DetectVarStoreMatch(det_ctx, pe->capids[x],
                                 (uint8_t *)str_ptr, capture_len,
-                                DETECT_FLOWVAR_TYPE_POSTMATCH);
+                                DETECT_VAR_TYPE_FLOW_POSTMATCH);
                     }
                 }
             }
@@ -717,10 +724,8 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
 
     uint8_t x;
     for (x = 0; x < pd->idx; x++) {
-        if (pd->captypes[x] == VAR_TYPE_FLOW_VAR) {
-            if (DetectFlowvarPostMatchSetup(s, pd->capids[x]) < 0)
-                goto error_nofree;
-        }
+        if (DetectFlowvarPostMatchSetup(s, pd->capids[x]) < 0)
+            goto error_nofree;
     }
 
     if (!(pd->flags & DETECT_PCRE_RELATIVE))
index 3797a2272c9f5ed4b8bef6a4d971453e13e9ae63..9207b537c0c7fe5fa28f8d623b32f911d2a8a7ca 100644 (file)
@@ -549,21 +549,19 @@ int SigMatchSignaturesRunPostMatch(ThreadVars *tv,
                                    const Signature *s)
 {
     /* run the packet match functions */
-    if (s->sm_arrays[DETECT_SM_LIST_POSTMATCH] != NULL) {
+    SigMatchData *smd = s->sm_arrays[DETECT_SM_LIST_POSTMATCH];
+    if (smd != NULL) {
         KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_POSTMATCH);
 
-        SigMatchData *smd = s->sm_arrays[DETECT_SM_LIST_POSTMATCH];
         SCLogDebug("running match functions, sm %p", smd);
 
-        if (smd != NULL) {
-            while (1) {
-                KEYWORD_PROFILING_START;
-                (void)sigmatch_table[smd->type].Match(tv, det_ctx, p, s, smd->ctx);
-                KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
-                if (smd->is_last)
-                    break;
-                smd++;
-            }
+        while (1) {
+            KEYWORD_PROFILING_START;
+            (void)sigmatch_table[smd->type].Match(tv, det_ctx, p, s, smd->ctx);
+            KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
+            if (smd->is_last)
+                break;
+            smd++;
         }
     }
 
@@ -1472,7 +1470,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
         }
         alerts++;
 next:
-        DetectFlowvarProcessList(det_ctx, pflow);
+        DetectVarProcessList(det_ctx, pflow, p);
         DetectReplaceFree(det_ctx);
         RULE_PROFILING_END(det_ctx, s, smatch, p);
 
index fd609f056b77a698a8f1342b605fa6de3c7b8de3..2394ab442ebbe4c4a87f440fe02b3d6683620f20 100644 (file)
@@ -490,20 +490,21 @@ typedef struct DetectReplaceList_ {
 } DetectReplaceList;
 
 /** only execute flowvar storage if rule matched */
-#define DETECT_FLOWVAR_TYPE_POSTMATCH   1
+#define DETECT_VAR_TYPE_FLOW_POSTMATCH      1
+#define DETECT_VAR_TYPE_PKT_POSTMATCH       2
 /** execute flowvar storage even if rule doesn't match (for lua) */
-#define DETECT_FLOWVAR_TYPE_ALWAYS      2
+#define DETECT_VAR_TYPE_ALWAYS              3
 
 /** list for flowvar store candidates, to be stored from
  *  post-match function */
-typedef struct DetectFlowvarList_ {
+typedef struct DetectVarList_ {
     uint32_t idx;                       /**< flowvar name idx */
     uint16_t len;                       /**< data len */
     int type;                           /**< type of store candidate POSTMATCH or ALWAYS */
     uint8_t *buffer;                    /**< alloc'd buffer, may be freed by
                                              post-match, post-non-match */
-    struct DetectFlowvarList_ *next;
-} DetectFlowvarList;
+    struct DetectVarList_ *next;
+} DetectVarList;
 
 typedef struct DetectEngineIPOnlyThreadCtx_ {
     uint8_t *sig_match_array; /* bit array of sig nums */
@@ -877,8 +878,8 @@ typedef struct DetectEngineThreadCtx_ {
 
     /* string to replace */
     DetectReplaceList *replist;
-    /* flowvars to store in post match function */
-    DetectFlowvarList *flowvarlist;
+    /* vars to store in post match function */
+    DetectVarList *varlist;
 
     /* Array in which the filestore keyword stores file id and tx id. If the
      * full signature matches, these are processed by a post-match filestore