]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/fast_pattern: allow for rule time registration
authorVictor Julien <victor@inliniac.net>
Fri, 24 Sep 2021 05:45:39 +0000 (07:45 +0200)
committerVictor Julien <vjulien@oisf.net>
Tue, 7 Dec 2021 06:56:36 +0000 (07:56 +0100)
In preparation of more dynamic logic in rule loading also doing
some registration, allow for buffers to be registered as fast_patterns
during rule parsing.

Leaves the register time registrations mostly as-is, but copies the
resulting list into the DetectEngineCtx and works with that onwards.
This list can then be extended.

src/detect-engine-mpm.c
src/detect-engine.c
src/detect-fast-pattern.c
src/detect-fast-pattern.h
src/detect.h

index 5376031d19be2f45c6e1f7d8110f517a1373cc4f..1efe53baea92e70780584c42ad2f4e40879a7f24 100644 (file)
@@ -201,7 +201,7 @@ void DetectAppLayerMpmRegisterByParentId(DetectEngineCtx *de_ctx,
             }
             am->id = de_ctx->app_mpms_list_cnt++;
 
-            SupportFastPatternForSigMatchList(am->sm_list, am->priority);
+            DetectEngineRegisterFastPatternForId(de_ctx, am->sm_list, am->priority);
             t->next = am;
             SCLogDebug("copied mpm registration for %s id %u "
                     "with parent %u and GetData %p",
@@ -370,7 +370,7 @@ void DetectPktMpmRegisterByParentId(DetectEngineCtx *de_ctx,
             }
             am->id = de_ctx->pkt_mpms_list_cnt++;
 
-            SupportFastPatternForSigMatchList(am->sm_list, am->priority);
+            DetectEngineRegisterFastPatternForId(de_ctx, am->sm_list, am->priority);
             t->next = am;
             SCLogDebug("copied mpm registration for %s id %u "
                     "with parent %u and GetData %p",
@@ -907,12 +907,13 @@ void RetrieveFPForSig(const DetectEngineCtx *de_ctx, Signature *s)
     int count_final_sm_list = 0;
     int priority;
 
-    const SCFPSupportSMList *tmp = sm_fp_support_smlist_list;
+    const SCFPSupportSMList *tmp = de_ctx->fp_support_smlist_list;
     while (tmp != NULL) {
         for (priority = tmp->priority;
              tmp != NULL && priority == tmp->priority;
              tmp = tmp->next)
         {
+            SCLogDebug("tmp->list_id %d tmp->priority %d", tmp->list_id, tmp->priority);
             if (tmp->list_id >= nlists)
                 continue;
             if (curr_sm_list[tmp->list_id] == 0)
index 5cb6e304529ae25299ca22a73250255420095784..b1700fefc45de96468ee105ca3f616ab2b358c2a 100644 (file)
@@ -52,6 +52,7 @@
 #include "detect-engine.h"
 #include "detect-engine-state.h"
 #include "detect-engine-payload.h"
+#include "detect-fast-pattern.h"
 #include "detect-byte-extract.h"
 #include "detect-content.h"
 #include "detect-uricontent.h"
@@ -2044,6 +2045,7 @@ static DetectEngineCtx *DetectEngineCtxInitReal(enum DetectEngineType type, cons
     DetectAddressMapInit(de_ctx);
     DetectMetadataHashInit(de_ctx);
     DetectBufferTypeSetupDetectEngine(de_ctx);
+    DetectEngineInitializeFastPatternList(de_ctx);
 
     /* init iprep... ignore errors for now */
     (void)SRepInit(de_ctx);
@@ -2155,6 +2157,7 @@ void DetectEngineCtxFree(DetectEngineCtx *de_ctx)
     if (de_ctx->sig_array)
         SCFree(de_ctx->sig_array);
 
+    DetectEngineFreeFastPatternList(de_ctx);
     SCClassConfDeInitContext(de_ctx);
     SCRConfDeInitContext(de_ctx);
 
index 36272731675fbea404805fc5f16498a87ef94959..f6302af6ecb7e03ab5452da59ab760103e3dbdb4 100644 (file)
@@ -49,7 +49,7 @@ static void DetectFastPatternRegisterTests(void);
 
 /* holds the list of sm match lists that need to be searched for a keyword
  * that has fp support */
-SCFPSupportSMList *sm_fp_support_smlist_list = NULL;
+static SCFPSupportSMList *g_fp_support_smlist_list = NULL;
 
 /**
  * \brief Checks if a particular list(Signature->sm_lists[]) is in the list
@@ -63,8 +63,9 @@ SCFPSupportSMList *sm_fp_support_smlist_list = NULL;
 int FastPatternSupportEnabledForSigMatchList(const DetectEngineCtx *de_ctx,
         const int list_id)
 {
-    if (sm_fp_support_smlist_list == NULL)
+    if (de_ctx->fp_support_smlist_list == NULL) {
         return 0;
+    }
 
     if (list_id == DETECT_SM_LIST_PMATCH)
         return 1;
@@ -72,18 +73,11 @@ int FastPatternSupportEnabledForSigMatchList(const DetectEngineCtx *de_ctx,
     return DetectEngineBufferTypeSupportsMpmGetById(de_ctx, list_id);
 }
 
-/**
- * \brief Lets one add a sm list id to be searched for potential fp supported
- *        keywords later.
- *
- * \param list_id SM list id.
- * \param priority Priority for this list.
- */
-void SupportFastPatternForSigMatchList(int list_id, int priority)
+static void Add(SCFPSupportSMList **list, const int list_id, const int priority)
 {
     SCFPSupportSMList *ip = NULL;
     /* insertion point - ip */
-    for (SCFPSupportSMList *tmp = sm_fp_support_smlist_list; tmp != NULL; tmp = tmp->next) {
+    for (SCFPSupportSMList *tmp = *list; tmp != NULL; tmp = tmp->next) {
         if (list_id == tmp->list_id) {
             SCLogDebug("SM list already registered.");
             return;
@@ -99,7 +93,7 @@ void SupportFastPatternForSigMatchList(int list_id, int priority)
         ip = tmp;
     }
 
-    if (sm_fp_support_smlist_list == NULL) {
+    if (*list == NULL) {
         SCFPSupportSMList *new = SCMalloc(sizeof(SCFPSupportSMList));
         if (unlikely(new == NULL))
             exit(EXIT_FAILURE);
@@ -107,8 +101,7 @@ void SupportFastPatternForSigMatchList(int list_id, int priority)
         new->list_id = list_id;
         new->priority = priority;
 
-        sm_fp_support_smlist_list = new;
-
+        *list = new;
         return;
     }
 
@@ -119,16 +112,32 @@ void SupportFastPatternForSigMatchList(int list_id, int priority)
     new->list_id = list_id;
     new->priority = priority;
     if (ip == NULL) {
-        new->next = sm_fp_support_smlist_list;
-        sm_fp_support_smlist_list = new;
+        new->next = *list;
+        *list = new;
     } else {
         new->next = ip->next;
         ip->next = new;
     }
-
     return;
 }
 
+/**
+ * \brief Lets one add a sm list id to be searched for potential fp supported
+ *        keywords later.
+ *
+ * \param list_id SM list id.
+ * \param priority Priority for this list.
+ */
+void SupportFastPatternForSigMatchList(int list_id, int priority)
+{
+    Add(&g_fp_support_smlist_list, list_id, priority);
+}
+
+void DetectEngineRegisterFastPatternForId(DetectEngineCtx *de_ctx, int list_id, int priority)
+{
+    Add(&de_ctx->fp_support_smlist_list, list_id, priority);
+}
+
 /**
  * \brief Registers the keywords(SMs) that should be given fp support.
  */
@@ -139,6 +148,38 @@ void SupportFastPatternForSigMatchTypes(void)
     /* other types are handled by DetectMpmAppLayerRegister() */
 }
 
+void DetectEngineInitializeFastPatternList(DetectEngineCtx *de_ctx)
+{
+    SCFPSupportSMList *last = NULL;
+    for (SCFPSupportSMList *tmp = g_fp_support_smlist_list; tmp != NULL; tmp = tmp->next) {
+        SCFPSupportSMList *n = SCCalloc(1, sizeof(*n));
+        if (n == NULL) {
+            FatalError(SC_ERR_FATAL, "out of memory: %s", strerror(errno));
+        }
+        n->list_id = tmp->list_id;
+        n->priority = tmp->priority;
+
+        // append
+        if (de_ctx->fp_support_smlist_list == NULL) {
+            last = de_ctx->fp_support_smlist_list = n;
+        } else {
+            BUG_ON(last == NULL);
+            last->next = n;
+            last = n;
+        }
+    }
+}
+
+void DetectEngineFreeFastPatternList(DetectEngineCtx *de_ctx)
+{
+    for (SCFPSupportSMList *tmp = de_ctx->fp_support_smlist_list; tmp != NULL;) {
+        SCFPSupportSMList *next = tmp->next;
+        SCFree(tmp);
+        tmp = next;
+    }
+    de_ctx->fp_support_smlist_list = NULL;
+}
+
 /**
  * \brief Registration function for fast_pattern keyword
  */
index 8617db1826ca2bd66fff661a4886527eeb273d55..af57540c74f1f3e903f7c5fcd89497f355ab32bb 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2010 Open Information Security Foundation
+/* Copyright (C) 2007-2021 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
 #ifndef __DETECT_FAST_PATTERN_H__
 #define __DETECT_FAST_PATTERN_H__
 
-typedef struct SCFPSupportSMList_ {
-    /* the list id.  Have a look at Signature->sm_lists[] */
-    int list_id;
-    int priority;
-
-    struct SCFPSupportSMList_ *next;
-} SCFPSupportSMList;
-
-extern SCFPSupportSMList *sm_fp_support_smlist_list;
-
 void SupportFastPatternForSigMatchList(int list_id, int priority);
 int FastPatternSupportEnabledForSigMatchList(const DetectEngineCtx *de_ctx,
         const int list_id);
 
 void SupportFastPatternForSigMatchTypes(void);
+void DetectEngineRegisterFastPatternForId(DetectEngineCtx *de_ctx, int list_id, int priority);
+
+void DetectEngineInitializeFastPatternList(DetectEngineCtx *de_ctx);
+void DetectEngineFreeFastPatternList(DetectEngineCtx *de_ctx);
 
 void DetectFastPatternRegister(void);
 
index c39ab27fa2f94c5f40f67a7e07a1eed084b702d9..99fc0faad812fa64b834788f31ce7db809470c27 100644 (file)
@@ -657,6 +657,12 @@ typedef struct DetectVarList_ {
     struct DetectVarList_ *next;
 } DetectVarList;
 
+typedef struct SCFPSupportSMList_ {
+    int list_id;
+    int priority;
+    struct SCFPSupportSMList_ *next;
+} SCFPSupportSMList;
+
 typedef struct DetectEngineIPOnlyThreadCtx_ {
     uint8_t *sig_match_array; /* bit array of sig nums */
     uint32_t sig_match_size;  /* size in bytes of the array */
@@ -943,6 +949,9 @@ typedef struct DetectEngineCtx_ {
     bool sm_types_prefilter[DETECT_TBLSIZE];
     bool sm_types_silent_error[DETECT_TBLSIZE];
 
+    /* list of Fast Pattern registrations. Initially filled using a copy of
+     * `g_fp_support_smlist_list`, then extended at rule loading time if needed */
+    SCFPSupportSMList *fp_support_smlist_list;
 } DetectEngineCtx;
 
 /* Engine groups profiles (low, medium, high, custom) */