From: Victor Julien Date: Mon, 15 Jan 2024 19:42:28 +0000 (+0100) Subject: mpm/ac: implement endswith X-Git-Tag: suricata-8.0.0-beta1~1646 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c312d670d4c33aeeba87da127656b045a5344c73;p=thirdparty%2Fsuricata.git mpm/ac: implement endswith When a pattern is using endswith, only consider it a match when it is the end of the data. Ticket: #6852. --- diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index d8630dd1c4..e7122e90ca 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -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)); } } } diff --git a/src/util-mpm-ac.c b/src/util-mpm-ac.c index e85b6e5032..891113ee83 100644 --- a/src/util-mpm-ac.c +++ b/src/util-mpm-ac.c @@ -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)); diff --git a/src/util-mpm-ac.h b/src/util-mpm-ac.h index f6cbe512b7..96b1c8e990 100644 --- a/src/util-mpm-ac.h +++ b/src/util-mpm-ac.h @@ -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; diff --git a/src/util-mpm.h b/src/util-mpm.h index 2df692040a..0bcd87899b 100644 --- a/src/util-mpm.h +++ b/src/util-mpm.h @@ -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;