detect/flowbits: add max usage per signature limit

Add a limit on the maximum number of times flowbits keyword that can be used in a
signature.

Task 8596
pull/15846/head
Shivani Bhardwaj 2 months ago committed by Victor Julien
parent 3462b126a3
commit 06db2e2698

@ -662,6 +662,8 @@ has values which can be managed by the user.
grouping:
tcp-priority-ports: 53, 80, 139, 443, 445, 1433, 3306, 3389, 6666, 6667, 8080
udp-priority-ports: 53, 135, 5060
flowbits:
max-per-signature: 8
At all of these options, you can add (or change) a value. Most
signatures have the adjustment to focus on one direction, meaning
@ -714,6 +716,11 @@ The engine shall then try to club the rules that use the ports defined
in groups of their own and put them on top of the list of rules to be matched
against traffic on "priority".
The ``flowbits`` option carries flowbits detection specific settings. With
``max-per-signature`` setting, it is possible to define how many times flowbits
keyword can be seen in any one signature. This does not include ``flowbits:noalert;``.
Minimum value allowed is 1 and the default is 8.
*Example 4 Detection-engine grouping tree*
.. image:: suricata-yaml/grouping_tree.png

@ -95,6 +95,8 @@
#define DETECT_ENGINE_DEFAULT_INSPECTION_RECURSION_LIMIT 3000
#define DEFAULT_MAX_FLOWBITS_PER_SIGNATURE 8
static int DetectEngineCtxLoadConf(DetectEngineCtx *);
static DetectEngineMasterCtx g_master_de_ctx = { SCMUTEX_INITIALIZER,
@ -2369,6 +2371,34 @@ static void InjectPackets(
}
}
static void DetectEngineLoadFlowbitSettings(DetectEngineCtx *de_ctx)
{
de_ctx->max_flowbits = DEFAULT_MAX_FLOWBITS_PER_SIGNATURE;
char varname[128] = "detect.flowbits.max-per-signature";
if (strlen(de_ctx->config_prefix) > 0) {
snprintf(varname, sizeof(varname), "%s.detect.flowbits.max-per-signature",
de_ctx->config_prefix);
}
const char *str;
if (SCConfGet(varname, &str) == 1) {
uint8_t val = 0;
int ret = StringParseUint8(&val, 10, 0, str);
if (ret > 0) {
if (val > 0) {
de_ctx->max_flowbits = val;
} else {
SCLogWarning("Invalid setting for flowbits.max-per-signature %d, resetting to the "
"default",
val);
}
} else {
SCLogWarning(
"Invalid setting for flowbits.max-per-signature, resetting to the default");
}
}
SCLogConfig("Setting flowbits.max-per-signature to %d", de_ctx->max_flowbits);
}
/** \internal
* \brief Update detect threads with new detect engine
*
@ -3158,6 +3188,8 @@ static int DetectEngineCtxLoadConf(DetectEngineCtx *de_ctx)
}
}
DetectEngineLoadFlowbitSettings(de_ctx);
de_ctx->prefilter_setting = DETECT_PREFILTER_MPM;
const char *pf_setting = NULL;
if (SCConfGet("detect.prefilter.default", &pf_setting) == 1 && pf_setting) {
@ -4088,7 +4120,6 @@ static int DetectEngineMultiTenantLoadTenant(uint32_t tenant_id, const char *fil
SCLogError("Loading signatures failed.");
goto error;
}
DetectEngineAddToMaster(de_ctx);
return 0;
@ -4998,6 +5029,7 @@ int DetectEngineReload(const SCInstance *suri)
DetectEngineDeReference(&old_de_ctx);
return -1;
}
if (SigLoadSignatures(new_de_ctx,
suri->sig_file, suri->sig_file_exclusive) != 0) {
DetectEngineCtxFree(new_de_ctx);

@ -450,6 +450,7 @@ int DetectFlowbitSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawst
DETECT_SM_LIST_MATCH) == NULL) {
goto error;
}
s->init_data->total_flowbits++;
break;
case DETECT_FLOWBITS_CMD_SET:
@ -459,6 +460,7 @@ int DetectFlowbitSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawst
DETECT_SM_LIST_POSTMATCH) == NULL) {
goto error;
}
s->init_data->total_flowbits++;
break;
// suppress coverity warning as scan-build-7 warns w/o this.

@ -2940,6 +2940,19 @@ static bool SigValidateProtoPkthdr(const Signature *s)
return true;
}
static bool SigValidateFlowbitUse(DetectEngineCtx *de_ctx, const Signature *s)
{
DEBUG_VALIDATE_BUG_ON(de_ctx->max_flowbits == 0);
if (s->init_data->total_flowbits > de_ctx->max_flowbits) {
SCLogError(
"rule %u: too many flowbits (max %u per signature)", s->id, de_ctx->max_flowbits);
return false;
}
return true;
}
/**
* \internal
* \brief validate and consolidate parsed signature
@ -2987,6 +3000,10 @@ static int SigValidateConsolidate(
SCReturnInt(0);
}
if (!SigValidateFlowbitUse(de_ctx, s)) {
SCReturnInt(0);
}
if (DetectProtoFinalizeSignature(s) != 0)
SCReturnInt(0);

@ -632,6 +632,10 @@ typedef struct SignatureInitData_ {
int list;
bool list_set;
/* Total number of times flowbits keyword is referenced in this signature (flowbits:noalert; not
* included) */
uint16_t total_flowbits;
DetectEngineTransforms transforms;
/** rule protocol settings */

@ -1895,6 +1895,9 @@ detect:
include-rules: false # very verbose
include-mpm-stats: false
flowbits:
max-per-signature: 8 # maximum number of flowbits keyword usage per signature, minimum value allowed is 1
# Select the multi pattern algorithm you want to run for scan/search the
# in the engine.
#

Loading…
Cancel
Save