From: Victor Julien Date: Thu, 29 May 2025 12:56:02 +0000 (+0200) Subject: detect: tables support per keyword X-Git-Tag: suricata-8.0.0-rc1~109 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=12f2f3f9f1828ed654ae088aa8b5f2ebaefba0d1;p=thirdparty%2Fsuricata.git detect: tables support per keyword Allow keywords to specify in which detect table they can function. E.g. the pre_flow table will not support flow keywords, as no flow is availble at this time. --- diff --git a/src/detect-engine.c b/src/detect-engine.c index c89c83053d..999c96c002 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -126,6 +126,28 @@ const struct SignatureProperties signature_properties[SIG_TYPE_MAX] = { // rule types documentation tag end: SignatureProperties // clang-format on +const char *DetectTableToString(enum FirewallTable table) +{ + switch (table) { + case FIREWALL_TABLE_NOT_SET: + return "not_set"; + case FIREWALL_TABLE_PACKET_PRE_FLOW: + return "pre_flow"; + case FIREWALL_TABLE_PACKET_PRE_STREAM: + return "pre_stream"; + case FIREWALL_TABLE_PACKET_FILTER: + return "packet_filter"; + case FIREWALL_TABLE_PACKET_TD: + return "packet_td"; + case FIREWALL_TABLE_APP_FILTER: + return "app_filter"; + case FIREWALL_TABLE_APP_TD: + return "app_td"; + default: + return "unknown"; + } +} + /** \brief register inspect engine at start up time * * \note errors are fatal */ diff --git a/src/detect-engine.h b/src/detect-engine.h index 557009fcfd..4d22b8075b 100644 --- a/src/detect-engine.h +++ b/src/detect-engine.h @@ -27,6 +27,8 @@ #include "detect.h" #include "suricata.h" +const char *DetectTableToString(enum FirewallTable table); + /* start up registry funcs */ int DetectBufferTypeRegister(const char *name); diff --git a/src/detect-flow.c b/src/detect-flow.c index 2a0ef1c9c2..6ed54152eb 100644 --- a/src/detect-flow.c +++ b/src/detect-flow.c @@ -76,6 +76,10 @@ void DetectFlowRegister (void) #endif sigmatch_table[DETECT_FLOW].SupportsPrefilter = PrefilterFlowIsPrefilterable; sigmatch_table[DETECT_FLOW].SetupPrefilter = PrefilterSetupFlow; + /* all but pre_flow */ + sigmatch_table[DETECT_FLOW].tables = + DETECT_TABLE_PACKET_PRE_STREAM_FLAG | DETECT_TABLE_PACKET_FILTER_FLAG | + DETECT_TABLE_PACKET_TD_FLAG | DETECT_TABLE_APP_FILTER_FLAG | DETECT_TABLE_APP_TD_FLAG; DetectSetupParseRegexes(PARSE_REGEX, &parse_regex); } diff --git a/src/detect-flowbits.c b/src/detect-flowbits.c index 49b7d13735..2d810112c2 100644 --- a/src/detect-flowbits.c +++ b/src/detect-flowbits.c @@ -83,6 +83,10 @@ void DetectFlowbitsRegister (void) sigmatch_table[DETECT_FLOWBITS].SupportsPrefilter = PrefilterFlowbitIsPrefilterable; sigmatch_table[DETECT_FLOWBITS].SetupPrefilter = PrefilterSetupFlowbits; + /* all but pre_flow */ + sigmatch_table[DETECT_FLOWBITS].tables = + DETECT_TABLE_PACKET_PRE_STREAM_FLAG | DETECT_TABLE_PACKET_FILTER_FLAG | + DETECT_TABLE_PACKET_TD_FLAG | DETECT_TABLE_APP_FILTER_FLAG | DETECT_TABLE_APP_TD_FLAG; DetectSetupParseRegexes(PARSE_REGEX, &parse_regex); } diff --git a/src/detect-parse.c b/src/detect-parse.c index d526d58219..6d8bec8d69 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -2446,6 +2446,27 @@ static void SigSetupPrefilter(DetectEngineCtx *de_ctx, Signature *s) SCReturn; } +/** \internal + * \brief check if signature's table requirement is supported by each of the keywords it uses. + */ +static bool DetectRuleValidateTable(const Signature *s) +{ + if (s->firewall_table == 0) + return true; + + const uint8_t table_as_flag = BIT_U8(s->firewall_table); + + for (SigMatch *sm = s->init_data->smlists[DETECT_SM_LIST_MATCH]; sm != NULL; sm = sm->next) { + const uint8_t kw_tables_supported = sigmatch_table[sm->type].tables; + if (kw_tables_supported != 0 && (kw_tables_supported & table_as_flag) == 0) { + SCLogError("rule %u uses hook \"%s\", but keyword \"%s\" doesn't support this hook", + s->id, DetectTableToString(s->firewall_table), sigmatch_table[sm->type].name); + return false; + } + } + return true; +} + static bool DetectFirewallRuleValidate(const DetectEngineCtx *de_ctx, const Signature *s) { if (s->init_data->hook.type == SIGNATURE_HOOK_TYPE_NOT_SET) { @@ -2907,6 +2928,9 @@ static Signature *SigInitHelper( if (de_ctx->flags & DE_HAS_FIREWALL) { DetectFirewallRuleSetTable(sig); } + if (DetectRuleValidateTable(sig) == false) { + goto error; + } if (sig->type == SIG_TYPE_IPONLY) { /* For IPOnly */ diff --git a/src/detect-tcp-wscale.c b/src/detect-tcp-wscale.c index 747a041255..b0785f77eb 100644 --- a/src/detect-tcp-wscale.c +++ b/src/detect-tcp-wscale.c @@ -55,6 +55,9 @@ void DetectTcpWscaleRegister(void) sigmatch_table[DETECT_TCP_WSCALE].SupportsPrefilter = PrefilterTcpWscaleIsPrefilterable; sigmatch_table[DETECT_TCP_WSCALE].SetupPrefilter = PrefilterSetupTcpWscale; sigmatch_table[DETECT_TCP_WSCALE].flags = SIGMATCH_SUPPORT_FIREWALL; + sigmatch_table[DETECT_TCP_WSCALE].tables = + (DETECT_TABLE_PACKET_PRE_FLOW_FLAG | DETECT_TABLE_PACKET_PRE_STREAM_FLAG | + DETECT_TABLE_PACKET_FILTER_FLAG | DETECT_TABLE_PACKET_TD_FLAG); } /** diff --git a/src/detect.h b/src/detect.h index 477e89f699..d6370ca603 100644 --- a/src/detect.h +++ b/src/detect.h @@ -550,13 +550,22 @@ enum SignatureHookType { SIGNATURE_HOOK_TYPE_APP, }; +// TODO should probably be renamed to DetectTable, similar for values enum FirewallTable { + FIREWALL_TABLE_NOT_SET = 0, FIREWALL_TABLE_PACKET_PRE_FLOW, FIREWALL_TABLE_PACKET_PRE_STREAM, FIREWALL_TABLE_PACKET_FILTER, FIREWALL_TABLE_PACKET_TD, FIREWALL_TABLE_APP_FILTER, FIREWALL_TABLE_APP_TD, + +#define DETECT_TABLE_PACKET_PRE_FLOW_FLAG BIT_U8(FIREWALL_TABLE_PACKET_PRE_FLOW) +#define DETECT_TABLE_PACKET_PRE_STREAM_FLAG BIT_U8(FIREWALL_TABLE_PACKET_PRE_STREAM) +#define DETECT_TABLE_PACKET_FILTER_FLAG BIT_U8(FIREWALL_TABLE_PACKET_FILTER) +#define DETECT_TABLE_PACKET_TD_FLAG BIT_U8(FIREWALL_TABLE_PACKET_TD) +#define DETECT_TABLE_APP_FILTER_FLAG BIT_U8(FIREWALL_TABLE_APP_FILTER) +#define DETECT_TABLE_APP_TD_FLAG BIT_U8(FIREWALL_TABLE_APP_TD) }; // dns:request_complete should add DetectBufferTypeGetByName("dns:request_complete"); @@ -1429,6 +1438,9 @@ typedef struct SigTableElmt_ { uint16_t flags; /* coccinelle: SigTableElmt:flags:SIGMATCH_ */ + /** bitfield of tables supported by this rule: used by DETECT_TABLE_*_FLAG flags. */ + uint8_t tables; + /** better keyword to replace the current one */ uint16_t alternative;