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.
pull/6680/head
Victor Julien 4 years ago committed by Victor Julien
parent db27244379
commit ecce116117

@ -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)

@ -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);

@ -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
*/

@ -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);

@ -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) */

Loading…
Cancel
Save