]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: initialization optimization
authorVictor Julien <vjulien@oisf.net>
Thu, 31 Mar 2022 16:00:57 +0000 (18:00 +0200)
committerJeff Lucovsky <jeff@lucovsky.org>
Fri, 27 May 2022 11:51:21 +0000 (07:51 -0400)
A lot of time was spent in `SigMatchListSMBelongsTo` for the `mpm_sm`.

Optimize this by keeping the value at hand during Signature parsing and
detection engine setup.

(cherry picked from commit 3352c0bee419818f138be5837729f63a9b31bb03)

src/detect-engine-analyzer.c
src/detect-engine-build.c
src/detect-engine-mpm.c
src/detect-engine.c
src/detect-parse.c
src/detect.h

index 4c8123035a584c12eb16b448e26427e03bebe10e..9ae652d772730e76035d426140ac0cbcfa10d9b9 100644 (file)
@@ -153,8 +153,9 @@ void EngineAnalysisFP(const DetectEngineCtx *de_ctx, const Signature *s, char *l
     int fast_pattern_set = 0;
     int fast_pattern_only_set = 0;
     int fast_pattern_chop_set = 0;
-    DetectContentData *fp_cd = NULL;
-    SigMatch *mpm_sm = s->init_data->mpm_sm;
+    const DetectContentData *fp_cd = NULL;
+    const SigMatch *mpm_sm = s->init_data->mpm_sm;
+    const int mpm_sm_list = s->init_data->mpm_sm_list;
 
     if (mpm_sm != NULL) {
         fp_cd = (DetectContentData *)mpm_sm->ctx;
@@ -186,7 +187,7 @@ void EngineAnalysisFP(const DetectEngineCtx *de_ctx, const Signature *s, char *l
     }
 
     fprintf(fp_engine_analysis_FD, "        Fast pattern matcher: ");
-    int list_type = SigMatchListSMBelongsTo(s, mpm_sm);
+    int list_type = mpm_sm_list;
     if (list_type == DETECT_SM_LIST_PMATCH)
         fprintf(fp_engine_analysis_FD, "content\n");
     else {
@@ -472,8 +473,9 @@ int PerCentEncodingMatch (uint8_t *content, uint8_t content_len)
 
 static void EngineAnalysisRulesPrintFP(const DetectEngineCtx *de_ctx, const Signature *s)
 {
-    DetectContentData *fp_cd = NULL;
-    SigMatch *mpm_sm = s->init_data->mpm_sm;
+    const DetectContentData *fp_cd = NULL;
+    const SigMatch *mpm_sm = s->init_data->mpm_sm;
+    const int mpm_sm_list = s->init_data->mpm_sm_list;
 
     if (mpm_sm != NULL) {
         fp_cd = (DetectContentData *)mpm_sm->ctx;
@@ -510,7 +512,7 @@ static void EngineAnalysisRulesPrintFP(const DetectEngineCtx *de_ctx, const Sign
 
     fprintf(rule_engine_analysis_FD, "\" on \"");
 
-    int list_type = SigMatchListSMBelongsTo(s, mpm_sm);
+    const int list_type = mpm_sm_list;
     if (list_type == DETECT_SM_LIST_PMATCH) {
         int payload = 0;
         int stream = 0;
@@ -1159,7 +1161,7 @@ void EngineAnalysisRules(const DetectEngineCtx *de_ctx,
         warn_offset_depth_alproto = 1;
     }
     if (s->init_data->mpm_sm != NULL && s->alproto == ALPROTO_HTTP &&
-        SigMatchListSMBelongsTo(s, s->init_data->mpm_sm) == DETECT_SM_LIST_PMATCH) {
+            s->init_data->mpm_sm_list == DETECT_SM_LIST_PMATCH) {
         rule_warning += 1;
         warn_non_alproto_fp_for_alproto_sig = 1;
     }
index 73f876718d6837b5c290d98eb7ca46b3ca97f84a..30e70b428ee29d0d02ef733273f2ed638b23ca63 100644 (file)
@@ -613,7 +613,7 @@ static int RuleGetMpmPatternSize(const Signature *s)
 {
     if (s->init_data->mpm_sm == NULL)
         return -1;
-    int mpm_list = SigMatchListSMBelongsTo(s, s->init_data->mpm_sm);
+    int mpm_list = s->init_data->mpm_sm_list;
     if (mpm_list < 0)
         return -1;
     const DetectContentData *cd = (const DetectContentData *)s->init_data->mpm_sm->ctx;
@@ -626,7 +626,7 @@ static int RuleMpmIsNegated(const Signature *s)
 {
     if (s->init_data->mpm_sm == NULL)
         return 0;
-    int mpm_list = SigMatchListSMBelongsTo(s, s->init_data->mpm_sm);
+    int mpm_list = s->init_data->mpm_sm_list;
     if (mpm_list < 0)
         return 0;
     const DetectContentData *cd = (const DetectContentData *)s->init_data->mpm_sm->ctx;
@@ -721,7 +721,7 @@ static json_t *RulesGroupPrintSghStats(const SigGroupHead *sgh,
             }
 
         } else {
-            int mpm_list = SigMatchListSMBelongsTo(s, s->init_data->mpm_sm);
+            int mpm_list = s->init_data->mpm_sm_list;
             BUG_ON(mpm_list < 0);
             const DetectContentData *cd = (const DetectContentData *)s->init_data->mpm_sm->ctx;
             uint32_t size = cd->content_len < 256 ? cd->content_len : 255;
@@ -1115,15 +1115,13 @@ static int RuleSetWhitelist(Signature *s)
 
             /* one byte pattern in packet/stream payloads */
         } else if (s->init_data->mpm_sm != NULL &&
-                   SigMatchListSMBelongsTo(s, s->init_data->mpm_sm) == DETECT_SM_LIST_PMATCH &&
-                   RuleGetMpmPatternSize(s) == 1)
-        {
+                   s->init_data->mpm_sm_list == DETECT_SM_LIST_PMATCH &&
+                   RuleGetMpmPatternSize(s) == 1) {
             SCLogDebug("Rule %u No MPM. Payload inspecting. Whitelisting SGH's.", s->id);
             wl = 55;
 
         } else if (DetectFlagsSignatureNeedsSynPackets(s) &&
-                   DetectFlagsSignatureNeedsSynOnlyPackets(s))
-        {
+                   DetectFlagsSignatureNeedsSynOnlyPackets(s)) {
             SCLogDebug("Rule %u Needs SYN, so inspected often. Whitelisting SGH's.", s->id);
             wl = 33;
         }
index 2ea28e7775974382cdc65777b97910e9baa4956d..335fce919b455817a3f4d828e43be397c6df5214 100644 (file)
@@ -776,7 +776,7 @@ static void PopulateMpmHelperAddPattern(MpmCtx *mpm_ctx,
 #define SGH_DIRECTION_TS(sgh) ((sgh)->init->direction & SIG_FLAG_TOSERVER)
 #define SGH_DIRECTION_TC(sgh) ((sgh)->init->direction & SIG_FLAG_TOCLIENT)
 
-static void SetMpm(Signature *s, SigMatch *mpm_sm)
+static void SetMpm(Signature *s, SigMatch *mpm_sm, const int mpm_sm_list)
 {
     if (s == NULL || mpm_sm == NULL)
         return;
@@ -799,6 +799,7 @@ static void SetMpm(Signature *s, SigMatch *mpm_sm)
         }
     }
     cd->flags |= DETECT_CONTENT_MPM;
+    s->init_data->mpm_sm_list = mpm_sm_list;
     s->init_data->mpm_sm = mpm_sm;
     return;
 }
@@ -844,7 +845,7 @@ void RetrieveFPForSig(const DetectEngineCtx *de_ctx, Signature *s)
     if (s->init_data->mpm_sm != NULL)
         return;
 
-    SigMatch *mpm_sm = NULL, *sm = NULL;
+    SigMatch *sm = NULL;
     const int nlists = s->init_data->smlists_array_size;
     int nn_sm_list[nlists];
     int n_sm_list[nlists];
@@ -869,7 +870,7 @@ void RetrieveFPForSig(const DetectEngineCtx *de_ctx, Signature *s)
             const DetectContentData *cd = (DetectContentData *)sm->ctx;
             /* fast_pattern set in rule, so using this pattern */
             if ((cd->flags & DETECT_CONTENT_FAST_PATTERN)) {
-                SetMpm(s, sm);
+                SetMpm(s, sm, list_id);
                 return;
             }
 
@@ -938,15 +939,29 @@ void RetrieveFPForSig(const DetectEngineCtx *de_ctx, Signature *s)
         }
     }
 
+    SigMatch *mpm_sm = NULL;
+    int mpm_sm_list = -1;
     for (int i = 0; i < count_final_sm_list; i++) {
         if (final_sm_list[i] >= (int)s->init_data->smlists_array_size)
             continue;
 
+        /* GetMpmForList may keep `mpm_sm` the same, so track if it changed */
+        SigMatch *prev_mpm_sm = mpm_sm;
         mpm_sm = GetMpmForList(s, final_sm_list[i], mpm_sm, max_len, skip_negated_content);
+        if (mpm_sm != prev_mpm_sm) {
+            mpm_sm_list = final_sm_list[i];
+        }
     }
 
+#ifdef DEBUG
+    if (mpm_sm != NULL) {
+        BUG_ON(mpm_sm_list == -1);
+        int check_list = SigMatchListSMBelongsTo(s, mpm_sm);
+        BUG_ON(check_list != mpm_sm_list);
+    }
+#endif
     /* assign to signature */
-    SetMpm(s, mpm_sm);
+    SetMpm(s, mpm_sm, mpm_sm_list);
     return;
 }
 
@@ -1243,7 +1258,7 @@ static void MpmStoreSetup(const DetectEngineCtx *de_ctx, MpmStore *ms)
                 continue;
             if (s->init_data->mpm_sm == NULL)
                 continue;
-            int list = SigMatchListSMBelongsTo(s, s->init_data->mpm_sm);
+            int list = s->init_data->mpm_sm_list;
             if (list < 0)
                 continue;
             if (list != ms->sm_list)
@@ -1352,7 +1367,7 @@ MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
         if (s->init_data->mpm_sm == NULL)
             continue;
 
-        int list = SigMatchListSMBelongsTo(s, s->init_data->mpm_sm);
+        int list = s->init_data->mpm_sm_list;
         if (list < 0)
             continue;
 
@@ -1444,7 +1459,10 @@ static MpmStore *MpmStorePrepareBufferAppLayer(DetectEngineCtx *de_ctx,
         if (s->init_data->mpm_sm == NULL)
             continue;
 
-        int list = SigMatchListSMBelongsTo(s, s->init_data->mpm_sm);
+        if ((s->flags & am->direction) == 0)
+            continue;
+
+        int list = s->init_data->mpm_sm_list;
         if (list < 0)
             continue;
 
@@ -1521,7 +1539,7 @@ static MpmStore *MpmStorePrepareBufferPkt(DetectEngineCtx *de_ctx,
         if (s->init_data->mpm_sm == NULL)
             continue;
 
-        int list = SigMatchListSMBelongsTo(s, s->init_data->mpm_sm);
+        int list = s->init_data->mpm_sm_list;
         if (list < 0)
             continue;
 
@@ -1772,7 +1790,7 @@ int DetectSetFastPatternAndItsId(DetectEngineCtx *de_ctx)
 
     for (s = de_ctx->sig_list; s != NULL; s = s->next) {
         if (s->init_data->mpm_sm != NULL) {
-            int sm_list = SigMatchListSMBelongsTo(s, s->init_data->mpm_sm);
+            int sm_list = s->init_data->mpm_sm_list;
             BUG_ON(sm_list == -1);
 
             DetectContentData *cd = (DetectContentData *)s->init_data->mpm_sm->ctx;
index 82462bd45793928d3e747a91026e743687a49c6a..c64fd80b32d9f11066fd4ccede577278b52cadfb 100644 (file)
@@ -437,7 +437,7 @@ static void AppendStreamInspectEngine(Signature *s, SigMatchData *stream, int di
     if (unlikely(new_engine == NULL)) {
         exit(EXIT_FAILURE);
     }
-    if (SigMatchListSMBelongsTo(s, s->init_data->mpm_sm) == DETECT_SM_LIST_PMATCH) {
+    if (s->init_data->mpm_sm_list == DETECT_SM_LIST_PMATCH) {
         SCLogDebug("stream is mpm");
         prepend = true;
         new_engine->mpm = true;
@@ -482,9 +482,7 @@ int DetectEngineAppInspectionEngine2Signature(DetectEngineCtx *de_ctx, Signature
     SigMatchData *ptrs[nlists];
     memset(&ptrs, 0, (nlists * sizeof(SigMatchData *)));
 
-    const int mpm_list = s->init_data->mpm_sm ?
-        SigMatchListSMBelongsTo(s, s->init_data->mpm_sm) :
-        -1;
+    const int mpm_list = s->init_data->mpm_sm ? s->init_data->mpm_sm_list : -1;
 
     const int files_id = DetectBufferTypeGetByName("files");
 
@@ -1523,6 +1521,7 @@ static int DetectEnginePktInspectionAppend(Signature *s, InspectionBufferPktInsp
     if (e == NULL)
         return -1;
 
+    e->mpm = s->init_data->mpm_sm_list == list_id;
     e->sm_list = list_id;
     e->sm_list_base = list_id;
     e->v1.Callback = Callback;
index f71bba9ed5f84ea67413f7d44e1086e11d374d94..7f0174a973f3296631f5435fc0bc8bfe7f83182b 100644 (file)
@@ -1273,6 +1273,7 @@ Signature *SigAlloc (void)
         SCFree(sig);
         return NULL;
     }
+    sig->init_data->mpm_sm_list = -1;
 
     sig->init_data->smlists_array_size = DetectBufferTypeMaxId();
     SCLogDebug("smlists size %u", sig->init_data->smlists_array_size);
index 78e6a77cd6177bb79c4f8338a0e400cc64f61f39..8f1904f74a9161ac68538f48646e1588f67917fb 100644 (file)
@@ -500,6 +500,8 @@ typedef struct SignatureInitData_ {
     /* used at init to determine max dsize */
     SigMatch *dsize_sm;
 
+    /* list id for `mpm_sm`. Should always match `SigMatchListSMBelongsTo(s, mpm_sm)`. */
+    int mpm_sm_list;
     /* the fast pattern added from this signature */
     SigMatch *mpm_sm;
     /* used to speed up init of prefilter */