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.
// 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 */
#include "detect.h"
#include "suricata.h"
+const char *DetectTableToString(enum FirewallTable table);
+
/* start up registry funcs */
int DetectBufferTypeRegister(const char *name);
#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);
}
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);
}
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) {
if (de_ctx->flags & DE_HAS_FIREWALL) {
DetectFirewallRuleSetTable(sig);
}
+ if (DetectRuleValidateTable(sig) == false) {
+ goto error;
+ }
if (sig->type == SIG_TYPE_IPONLY) {
/* For IPOnly */
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);
}
/**
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");
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;