From: Victor Julien Date: Fri, 24 Sep 2021 05:45:39 +0000 (+0200) Subject: detect/fast_pattern: allow for rule time registration X-Git-Tag: suricata-7.0.0-beta1~1135 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ecce116117cf3ea2d74c3916602dee40ee1c64fd;p=thirdparty%2Fsuricata.git detect/fast_pattern: allow for rule time registration 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. --- diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 5376031d19..1efe53baea 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -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) diff --git a/src/detect-engine.c b/src/detect-engine.c index 5cb6e30452..b1700fefc4 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -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); diff --git a/src/detect-fast-pattern.c b/src/detect-fast-pattern.c index 3627273167..f6302af6ec 100644 --- a/src/detect-fast-pattern.c +++ b/src/detect-fast-pattern.c @@ -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 */ diff --git a/src/detect-fast-pattern.h b/src/detect-fast-pattern.h index 8617db1826..af57540c74 100644 --- a/src/detect-fast-pattern.h +++ b/src/detect-fast-pattern.h @@ -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 @@ -24,21 +24,15 @@ #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); diff --git a/src/detect.h b/src/detect.h index c39ab27fa2..99fc0faad8 100644 --- a/src/detect.h +++ b/src/detect.h @@ -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) */