#include "util-lua.h"
#endif
+#ifdef UNITTESTS
+thread_local uint32_t ut_inspection_recursion_counter = 0;
+#endif
+
+struct DetectEngineContentInspectionCtx {
+ struct {
+ uint32_t count;
+ const uint32_t limit;
+ } recursion;
+};
+
/**
* \brief Run the actual payload match functions
*
* For accounting the last match in relative matching the
* det_ctx->buffer_offset int is used.
*
- * \param de_ctx Detection engine context
* \param det_ctx Detection engine thread context
* \param s Signature to inspect
* \param sm SigMatch to inspect
* \retval 0 no match
* \retval 1 match
*/
-static int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx,
- DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p,
- Flow *f, const uint8_t *buffer, const uint32_t buffer_len,
+static int DetectEngineContentInspectionInternal(DetectEngineThreadCtx *det_ctx,
+ struct DetectEngineContentInspectionCtx *ctx, const Signature *s, const SigMatchData *smd,
+ Packet *p, Flow *f, const uint8_t *buffer, const uint32_t buffer_len,
const uint32_t stream_start_offset, const uint8_t flags,
const enum DetectContentInspectionType inspection_mode)
{
SCEnter();
KEYWORD_PROFILING_START;
- det_ctx->inspection_recursion_counter++;
-
- if (unlikely(det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit)) {
+ ctx->recursion.count++;
+ if (unlikely(ctx->recursion.count == ctx->recursion.limit)) {
KEYWORD_PROFILING_END(det_ctx, smd->type, 0);
SCReturnInt(-1);
}
/* see if the next buffer keywords match. If not, we will
* search for another occurrence of this content and see
* if the others match then until we run out of matches */
- int r = DetectEngineContentInspectionInternal(de_ctx, det_ctx, s, smd + 1,
- p, f, buffer, buffer_len, stream_start_offset, flags,
- inspection_mode);
+ int r = DetectEngineContentInspectionInternal(det_ctx, ctx, s, smd + 1, p,
+ f, buffer, buffer_len, stream_start_offset, flags, inspection_mode);
if (r == 1) {
SCReturnInt(1);
} else if (r == -1) {
/* see if the next payload keywords match. If not, we will
* search for another occurrence of this pcre and see
* if the others match, until we run out of matches */
- r = DetectEngineContentInspectionInternal(de_ctx, det_ctx, s, smd + 1, p, f, buffer,
+ r = DetectEngineContentInspectionInternal(det_ctx, ctx, s, smd + 1, p, f, buffer,
buffer_len, stream_start_offset, flags, inspection_mode);
if (r == 1) {
SCReturnInt(1);
if (s->sm_arrays[DETECT_SM_LIST_BASE64_DATA] != NULL) {
if (det_ctx->base64_decoded_len) {
KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
- int r = DetectEngineContentInspectionInternal(de_ctx, det_ctx, s,
+ int r = DetectEngineContentInspectionInternal(det_ctx, ctx, s,
s->sm_arrays[DETECT_SM_LIST_BASE64_DATA], NULL, f,
det_ctx->base64_decoded, det_ctx->base64_decoded_len, 0,
DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
* the buffer portion of the signature matched. */
if (!smd->is_last) {
KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
- int r = DetectEngineContentInspectionInternal(de_ctx, det_ctx, s, smd + 1, p, f, buffer,
+ int r = DetectEngineContentInspectionInternal(det_ctx, ctx, s, smd + 1, p, f, buffer,
buffer_len, stream_start_offset, flags, inspection_mode);
SCReturnInt(r);
}
const uint32_t buffer_len, const uint32_t stream_start_offset, const uint8_t flags,
const enum DetectContentInspectionType inspection_mode)
{
+ struct DetectEngineContentInspectionCtx ctx = { .recursion.count = 0,
+ .recursion.limit = de_ctx->inspection_recursion_limit };
det_ctx->buffer_offset = 0;
- det_ctx->inspection_recursion_counter = 0;
- int r = DetectEngineContentInspectionInternal(de_ctx, det_ctx, s, smd, p, f, buffer, buffer_len,
+ int r = DetectEngineContentInspectionInternal(det_ctx, &ctx, s, smd, p, f, buffer, buffer_len,
stream_start_offset, flags, inspection_mode);
+#ifdef UNITTESTS
+ ut_inspection_recursion_counter = ctx.recursion.count;
+#endif
if (r == 1)
return true;
else
const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const InspectionBuffer *b,
const enum DetectContentInspectionType inspection_mode)
{
+ struct DetectEngineContentInspectionCtx ctx = { .recursion.count = 0,
+ .recursion.limit = de_ctx->inspection_recursion_limit };
+
det_ctx->buffer_offset = 0;
- det_ctx->inspection_recursion_counter = 0;
- int r = DetectEngineContentInspectionInternal(de_ctx, det_ctx, s, smd, p, f, b->inspect,
+ int r = DetectEngineContentInspectionInternal(det_ctx, &ctx, s, smd, p, f, b->inspect,
b->inspect_len, b->inspect_offset, b->flags, inspection_mode);
+#ifdef UNITTESTS
+ ut_inspection_recursion_counter = ctx.recursion.count;
+#endif
if (r == 1)
return true;
else
#include "../detect.h"
#include "detect-engine-build.h"
+extern thread_local uint32_t ut_inspection_recursion_counter;
+
#define TEST_HEADER \
ThreadVars tv; \
memset(&tv, 0, sizeof(tv)); \
Flow f; \
memset(&f, 0, sizeof(f));
-#define TEST_RUN(buf, buflen, sig, match, steps) \
-{ \
- DetectEngineCtx *de_ctx = DetectEngineCtxInit(); \
- FAIL_IF_NULL(de_ctx); \
- DetectEngineThreadCtx *det_ctx = NULL; \
- char rule[2048]; \
- snprintf(rule, sizeof(rule), "alert tcp any any -> any any (%s sid:1; rev:1;)", (sig)); \
- Signature *s = DetectEngineAppendSig(de_ctx, rule); \
- FAIL_IF_NULL(s); \
- SigGroupBuild(de_ctx); \
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); \
- FAIL_IF_NULL(det_ctx); \
- int r = DetectEngineContentInspection(de_ctx, det_ctx, \
- s, s->sm_arrays[DETECT_SM_LIST_PMATCH], NULL, &f, \
- (uint8_t *)(buf), (buflen), 0, DETECT_CI_FLAGS_SINGLE, \
- DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD); \
- FAIL_IF_NOT(r == (match)); \
- FAIL_IF_NOT(det_ctx->inspection_recursion_counter == (steps)); \
- DetectEngineThreadCtxDeinit(&tv, det_ctx); \
- DetectEngineCtxFree(de_ctx); \
-}
+#define TEST_RUN(buf, buflen, sig, match, steps) \
+ { \
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit(); \
+ FAIL_IF_NULL(de_ctx); \
+ DetectEngineThreadCtx *det_ctx = NULL; \
+ char rule[2048]; \
+ snprintf(rule, sizeof(rule), "alert tcp any any -> any any (%s sid:1; rev:1;)", (sig)); \
+ Signature *s = DetectEngineAppendSig(de_ctx, rule); \
+ FAIL_IF_NULL(s); \
+ SigGroupBuild(de_ctx); \
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); \
+ FAIL_IF_NULL(det_ctx); \
+ int r = DetectEngineContentInspection(de_ctx, det_ctx, s, \
+ s->sm_arrays[DETECT_SM_LIST_PMATCH], NULL, &f, (uint8_t *)(buf), (buflen), 0, \
+ DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD); \
+ FAIL_IF_NOT(r == (match)); \
+ FAIL_IF_NOT(ut_inspection_recursion_counter == (steps)); \
+ DetectEngineThreadCtxDeinit(&tv, det_ctx); \
+ DetectEngineCtxFree(de_ctx); \
+ }
#define TEST_FOOTER \
PASS