From af7fad551408fc1d04ea30606dac7d266a4af743 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Fri, 16 Jan 2026 14:08:59 +0100 Subject: [PATCH] detect: allocate arrays on the heap buffer_type_id is a u32 Ticket: 8001 --- src/detect-engine-analyzer.c | 11 +++++++-- src/detect-engine-build.c | 44 +++++++++++++++++++++++------------- src/detect-engine-mpm.c | 42 ++++++++++++++++++++++------------ 3 files changed, 65 insertions(+), 32 deletions(-) diff --git a/src/detect-engine-analyzer.c b/src/detect-engine-analyzer.c index 38d0d6f04c..2908c77788 100644 --- a/src/detect-engine-analyzer.c +++ b/src/detect-engine-analyzer.c @@ -1562,8 +1562,14 @@ void DumpPatterns(DetectEngineCtx *de_ctx) return; SCJsonBuilder *root_jb = SCJbNewObject(); - SCJsonBuilder *arrays[de_ctx->buffer_type_id]; - memset(&arrays, 0, sizeof(SCJsonBuilder *) * de_ctx->buffer_type_id); + if (root_jb == NULL) { + return; + } + SCJsonBuilder **arrays = SCCalloc(de_ctx->buffer_type_id, sizeof(SCJsonBuilder *)); + if (arrays == NULL) { + SCJbFree(root_jb); + return; + } SCJbOpenArray(root_jb, "buffers"); @@ -1631,6 +1637,7 @@ void DumpPatterns(DetectEngineCtx *de_ctx) } SCMutexUnlock(&g_rules_analyzer_write_m); SCJbFree(root_jb); + SCFree(arrays); HashListTableFree(de_ctx->pattern_hash_table); de_ctx->pattern_hash_table = NULL; diff --git a/src/detect-engine-build.c b/src/detect-engine-build.c index 0b00de5207..c9d27911e1 100644 --- a/src/detect-engine-build.c +++ b/src/detect-engine-build.c @@ -600,6 +600,13 @@ static bool RuleMpmIsNegated(const Signature *s) return (cd->flags & DETECT_CONTENT_NEGATED) != 0; } +typedef struct MpmStat { + uint32_t total; + uint32_t cnt; + uint32_t min; + uint32_t max; +} MpmStat; + static SCJsonBuilder *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, const SigGroupHead *sgh, const int add_rules, const int add_mpm_stats) { @@ -618,13 +625,12 @@ static SCJsonBuilder *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, int max_buffer_type_id = de_ctx->buffer_type_id; - struct { - uint32_t total; - uint32_t cnt; - uint32_t min; - uint32_t max; - } mpm_stats[max_buffer_type_id]; - memset(mpm_stats, 0x00, sizeof(mpm_stats)); + MpmStat *mpm_stats = NULL; + if (add_mpm_stats) { + mpm_stats = SCCalloc(max_buffer_type_id, sizeof(MpmStat)); + if (mpm_stats == NULL) + return NULL; + } uint32_t alstats[g_alproto_max]; memset(alstats, 0, g_alproto_max * sizeof(uint32_t)); @@ -634,12 +640,16 @@ static SCJsonBuilder *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, memset(alproto_mpm_bufs, 0, sizeof(alproto_mpm_bufs)); DEBUG_VALIDATE_BUG_ON(sgh->init == NULL); - if (sgh->init == NULL) + if (sgh->init == NULL) { + SCFree(mpm_stats); return NULL; + } SCJsonBuilder *js = SCJbNewObject(); - if (unlikely(js == NULL)) + if (unlikely(js == NULL)) { + SCFree(mpm_stats); return NULL; + } SCJbSetUint(js, "id", sgh->id); @@ -730,13 +740,14 @@ static SCJsonBuilder *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, mpms_max = w; BUG_ON(mpm_list >= max_buffer_type_id); - mpm_stats[mpm_list].total += w; - mpm_stats[mpm_list].cnt++; - if (mpm_stats[mpm_list].min == 0 || w < mpm_stats[mpm_list].min) - mpm_stats[mpm_list].min = w; - if (w > mpm_stats[mpm_list].max) - mpm_stats[mpm_list].max = w; - + if (mpm_stats != NULL) { + mpm_stats[mpm_list].total += w; + mpm_stats[mpm_list].cnt++; + if (mpm_stats[mpm_list].min == 0 || w < mpm_stats[mpm_list].min) + mpm_stats[mpm_list].min = w; + if (w > mpm_stats[mpm_list].max) + mpm_stats[mpm_list].max = w; + } mpm_cnt++; if (w < 10) { @@ -861,6 +872,7 @@ static SCJsonBuilder *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, SCJbSetUint(js, "score", sgh->init->score); SCJbClose(js); + SCFree(mpm_stats); return js; } diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 9714539f43..60389c498e 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -1536,18 +1536,23 @@ static const DetectBufferMpmRegistry *GetByMpmStore( void MpmStoreReportStats(const DetectEngineCtx *de_ctx) { HashListTableBucket *htb = NULL; + uint32_t *appstats = NULL; + uint32_t *pktstats = NULL; + uint32_t *framestats = NULL; uint32_t stats[MPMB_MAX] = {0}; - DEBUG_VALIDATE_BUG_ON(de_ctx->buffer_type_id > UINT16_MAX); - int app_mpms_cnt = de_ctx->buffer_type_id; - uint32_t appstats[app_mpms_cnt + 1]; // +1 to silence scan-build - memset(&appstats, 0x00, sizeof(appstats)); - int pkt_mpms_cnt = de_ctx->buffer_type_id; - uint32_t pktstats[pkt_mpms_cnt + 1]; // +1 to silence scan-build - memset(&pktstats, 0x00, sizeof(pktstats)); - int frame_mpms_cnt = de_ctx->buffer_type_id; - uint32_t framestats[frame_mpms_cnt + 1]; // +1 to silence scan-build - memset(&framestats, 0x00, sizeof(framestats)); + appstats = SCCalloc(de_ctx->buffer_type_id, sizeof(uint32_t)); + if (appstats == NULL) { + goto end; + } + pktstats = SCCalloc(de_ctx->buffer_type_id, sizeof(uint32_t)); + if (pktstats == NULL) { + goto end; + } + framestats = SCCalloc(de_ctx->buffer_type_id, sizeof(uint32_t)); + if (framestats == NULL) { + goto end; + } for (htb = HashListTableGetListHead(de_ctx->mpm_hash_table); htb != NULL; @@ -1623,6 +1628,13 @@ void MpmStoreReportStats(const DetectEngineCtx *de_ctx) um = um->next; } } +end: + if (appstats) + SCFree(appstats); + if (pktstats) + SCFree(pktstats); + if (framestats) + SCFree(framestats); } /** @@ -2091,10 +2103,10 @@ static void PrepareMpms(DetectEngineCtx *de_ctx, SigGroupHead *sh) AppProto engines[max_buffer_id][g_alproto_max]; memset(engines, 0, sizeof(engines)); - int engines_idx[max_buffer_id]; - memset(engines_idx, 0, sizeof(engines_idx)); - int types[max_buffer_id]; - memset(types, 0, sizeof(types)); + int *engines_idx = SCCalloc(max_buffer_id, sizeof(int)); + BUG_ON(engines_idx == NULL); + int *types = SCCalloc(max_buffer_id, sizeof(int)); + BUG_ON(types == NULL); /* flag the list+directions we have engines for as active */ for (DetectBufferMpmRegistry *a = de_ctx->pkt_mpms_list; a != NULL; a = a->next) { @@ -2331,6 +2343,8 @@ static void PrepareMpms(DetectEngineCtx *de_ctx, SigGroupHead *sh) } } HashListTableFree(bufs); + SCFree(engines_idx); + SCFree(types); } /** \brief Prepare the pattern matcher ctx in a sig group head.