]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
mpm/ac: implement endswith
authorVictor Julien <vjulien@oisf.net>
Mon, 15 Jan 2024 19:42:28 +0000 (20:42 +0100)
committerVictor Julien <victor@inliniac.net>
Sat, 16 Mar 2024 08:29:34 +0000 (09:29 +0100)
When a pattern is using endswith, only consider it a match when it
is the end of the data.

Ticket: #6852.

src/detect-engine-mpm.c
src/util-mpm-ac.c
src/util-mpm-ac.h
src/util-mpm.h

index d8630dd1c4670d47792325adaa385fa3cab5ca4e..e7122e90caa9790049439331956831b56fc74736 100644 (file)
@@ -1559,6 +1559,9 @@ static void MpmStoreSetup(const DetectEngineCtx *de_ctx, MpmStore *ms)
 
     MpmInitCtx(ms->mpm_ctx, de_ctx->mpm_matcher);
 
+    const bool mpm_supports_endswith =
+            (mpm_table[de_ctx->mpm_matcher].feature_flags & MPM_FEATURE_FLAG_ENDSWITH) != 0;
+
     /* add the patterns */
     for (sig = 0; sig < (ms->sid_array_size * 8); sig++) {
         if (ms->sid_array[sig / 8] & (1 << (sig % 8))) {
@@ -1585,8 +1588,11 @@ static void MpmStoreSetup(const DetectEngineCtx *de_ctx, MpmStore *ms)
             }
 
             if (!skip) {
-                PopulateMpmHelperAddPattern(ms->mpm_ctx,
-                        cd, s, 0, (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP));
+                uint8_t flags = 0;
+                if ((cd->flags & DETECT_CONTENT_ENDS_WITH) && mpm_supports_endswith)
+                    flags = MPM_PATTERN_FLAG_ENDSWITH;
+                PopulateMpmHelperAddPattern(
+                        ms->mpm_ctx, cd, s, flags, (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP));
             }
         }
     }
index e85b6e503215ec7e548c73f8cb25d2bfe9eaeb48..891113ee837fe27d7c33f9a923303334943611c8 100644 (file)
@@ -781,6 +781,8 @@ int SCACPreparePatterns(MpmCtx *mpm_ctx)
         }
         ctx->pid_pat_list[ctx->parray[i]->id].offset = ctx->parray[i]->offset;
         ctx->pid_pat_list[ctx->parray[i]->id].depth = ctx->parray[i]->depth;
+        ctx->pid_pat_list[ctx->parray[i]->id].endswith =
+                (ctx->parray[i]->flags & MPM_PATTERN_FLAG_ENDSWITH) != 0;
 
         /* ACPatternList now owns this memory */
         //SCLogInfo("ctx->parray[i]->sids_size %u", ctx->parray[i]->sids_size);
@@ -965,6 +967,8 @@ uint32_t SCACSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx,
 
                         if (offset < (int)pat->offset || (pat->depth && i > pat->depth))
                             continue;
+                        if (pat->endswith && (uint32_t)offset + pat->patlen != buflen)
+                            continue;
 
                         if (SCMemcmp(pat->cs, buf + offset, pat->patlen) != 0) {
                             /* inside loop */
@@ -981,6 +985,8 @@ uint32_t SCACSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx,
 
                         if (offset < (int)pat->offset || (pat->depth && i > pat->depth))
                             continue;
+                        if (pat->endswith && (uint32_t)offset + pat->patlen != buflen)
+                            continue;
 
                         if (!(bitarray[pids[k] / 8] & (1 << (pids[k] % 8)))) {
                             bitarray[pids[k] / 8] |= (1 << (pids[k] % 8));
@@ -1007,6 +1013,8 @@ uint32_t SCACSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx,
 
                         if (offset < (int)pat->offset || (pat->depth && i > pat->depth))
                             continue;
+                        if (pat->endswith && (uint32_t)offset + pat->patlen != buflen)
+                            continue;
 
                         if (SCMemcmp(pat->cs, buf + offset,
                                      pat->patlen) != 0) {
@@ -1024,6 +1032,8 @@ uint32_t SCACSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx,
 
                         if (offset < (int)pat->offset || (pat->depth && i > pat->depth))
                             continue;
+                        if (pat->endswith && (uint32_t)offset + pat->patlen != buflen)
+                            continue;
 
                         if (!(bitarray[pids[k] / 8] & (1 << (pids[k] % 8)))) {
                             bitarray[pids[k] / 8] |= (1 << (pids[k] % 8));
index f6cbe512b7790f62fb07f43194a0dacc4190f110..96b1c8e990ee44d2975e3e93d9a681be791a1141 100644 (file)
@@ -37,6 +37,8 @@ typedef struct SCACPatternList_ {
     uint16_t offset;
     uint16_t depth;
 
+    bool endswith;
+
     /* sid(s) for this pattern */
     uint32_t sids_size;
     SigIntId *sids;
index 2df692040aba55570a04a4616714ee9caa2ed526..0bcd87899b6c83f2e30b760a6d298c0e62a4f7b9 100644 (file)
@@ -137,9 +137,11 @@ typedef struct MpmCtxFactoryContainer_ {
 /** the ctx uses it's own internal id instead of
  *  what is passed through the API */
 #define MPM_PATTERN_CTX_OWNS_ID     0x20
+#define MPM_PATTERN_FLAG_ENDSWITH   0x40
 
-#define MPM_FEATURE_FLAG_DEPTH  BIT_U8(0)
-#define MPM_FEATURE_FLAG_OFFSET BIT_U8(1)
+#define MPM_FEATURE_FLAG_DEPTH    BIT_U8(0)
+#define MPM_FEATURE_FLAG_OFFSET   BIT_U8(1)
+#define MPM_FEATURE_FLAG_ENDSWITH BIT_U8(2)
 
 typedef struct MpmTableElmt_ {
     const char *name;