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.
pull/13410/head
Victor Julien 6 months ago committed by Victor Julien
parent a88d58e531
commit 12f2f3f9f1

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

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

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

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

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

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

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

Loading…
Cancel
Save