From 5e167c2bac88b8547be4e497298a259e9540e71b Mon Sep 17 00:00:00 2001 From: Samaresh Kumar Singh Date: Tue, 9 Jun 2026 16:55:59 -0500 Subject: [PATCH 1/2] detect: guard duplicate bytemath endian macro Newer cbindgen (>= 0.29.3) exports the Rust DETECT_BYTEMATH_ENDIAN_DEFAULT constant into rust-bindings.h as a macro, which collides under -Werror with the macro defined under UNITTESTS in detect-bytemath.c and breaks the build. Guard the C definition with ifndef so it is only defined when the binding did not, keeping the build working with older cbindgen that does not emit it. --- src/detect-bytemath.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/detect-bytemath.c b/src/detect-bytemath.c index 0ebd8d551167..cf24d1adb444 100644 --- a/src/detect-bytemath.c +++ b/src/detect-bytemath.c @@ -58,7 +58,13 @@ static int DetectByteMathSetup(DetectEngineCtx *, Signature *, const char *); #ifdef UNITTESTS +/* Newer cbindgen (>= 0.29.3) exports the Rust DETECT_BYTEMATH_ENDIAN_DEFAULT + * constant into rust-bindings.h as a macro. Only define it here when that + * binding did not, to avoid a -Werror macro redefinition while still building + * with older cbindgen versions that do not emit it. */ +#ifndef DETECT_BYTEMATH_ENDIAN_DEFAULT #define DETECT_BYTEMATH_ENDIAN_DEFAULT (uint8_t) BigEndian +#endif #define DETECT_BYTEMATH_BASE_DEFAULT (uint8_t) BaseDec static void DetectByteMathRegisterTests(void); From 521ae08d97fa814accf5f29647e1fba9e3e0fa06 Mon Sep 17 00:00:00 2001 From: Samaresh Kumar Singh Date: Tue, 9 Jun 2026 16:56:00 -0500 Subject: [PATCH 2/2] detect: fail thread init on keyword ctx error DetectEngineThreadCtxInitKeywords returns TM_ECODE_FAILED when a per-thread keyword init fails (for example DetectFilemagicThreadInit), but ThreadCtxDoInit discarded that result and still returned OK. The detect thread then ran with a partially initialized keyword context array, producing indeterminate results. Propagate the failure so the callers abort thread init and clean up. Add a unit test that registers a keyword whose thread init fails and verifies that DetectEngineThreadCtxInit reports the failure. Ticket: #8237 --- src/detect-engine.c | 52 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/src/detect-engine.c b/src/detect-engine.c index c526154027b2..0373ef9ab368 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -3423,8 +3423,8 @@ static TmEcode ThreadCtxDoInit (DetectEngineCtx *de_ctx, DetectEngineThreadCtx * } det_ctx->multi_inspect.to_clear_idx = 0; - - DetectEngineThreadCtxInitKeywords(de_ctx, det_ctx); + if (DetectEngineThreadCtxInitKeywords(de_ctx, det_ctx) != TM_ECODE_OK) + return TM_ECODE_FAILED; DetectEngineThreadCtxInitGlobalKeywords(det_ctx); #ifdef PROFILE_RULES SCProfilingRuleThreadSetup(de_ctx->profile_ctx, det_ctx); @@ -5435,6 +5435,52 @@ static int DetectEngineTest09(void) PASS; } +/** \brief keyword thread-context init stub that always fails, used to mimic a + * failing per-thread keyword init such as DetectFilemagicThreadInit. */ +static void *DetectEngineFailingThreadKeywordInit(void *data) +{ + (void)data; + return NULL; +} + +static void DetectEngineNoopThreadKeywordFree(void *ctx) +{ + (void)ctx; +} + +/** \test Ticket #8237: a failing per-thread keyword init must make the detect + * thread context init fail rather than silently continuing with a partially + * initialized keyword context array. */ +static int DetectEngineThreadCtxInitKeywordFailTest(void) +{ + ThreadVars th_v; + memset(&th_v, 0, sizeof(th_v)); + DetectEngineThreadCtx *det_ctx = NULL; + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + FAIL_IF_NULL(de_ctx); + de_ctx->flags |= DE_QUIET; + + Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (sid:1;)"); + FAIL_IF_NULL(s); + + SigGroupBuild(de_ctx); + + /* Register a keyword whose per-thread init fails (returns NULL). */ + int id = DetectRegisterThreadCtxFuncs(de_ctx, "test_failing_keyword", + DetectEngineFailingThreadKeywordInit, NULL, DetectEngineNoopThreadKeywordFree, 0); + FAIL_IF(id < 0); + + /* Thread context init must report failure and not hand back a context. */ + TmEcode r = DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + FAIL_IF(r != TM_ECODE_FAILED); + FAIL_IF_NOT_NULL(det_ctx); + + DetectEngineCtxFree(de_ctx); + + PASS; +} + #endif void DetectEngineRegisterTests(void) @@ -5446,5 +5492,7 @@ void DetectEngineRegisterTests(void) UtRegisterTest("DetectEngineTest04", DetectEngineTest04); UtRegisterTest("DetectEngineTest08", DetectEngineTest08); UtRegisterTest("DetectEngineTest09", DetectEngineTest09); + UtRegisterTest( + "DetectEngineThreadCtxInitKeywordFailTest", DetectEngineThreadCtxInitKeywordFailTest); #endif }