From fa7641060330c0d0501ce47961d27eee67ed2f0b Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Thu, 6 Aug 2026 10:37:28 +0000 Subject: [PATCH] detect: fix heap buffer overflow in DetectRunTx post-rule match PrefilterPostRuleMatch() repopulates det_ctx->pmq with flowbits:isset candidates after a matching flowbits:set rule is found. The subsequent append loop writes directly into det_ctx->tx_candidates[] without first checking that the array has room. The buffer was initially sized for prefilter results only not accounting for post-rule additions. When array_idx already equals tx_candidates_size, the writes go past the end of the heap-allocated block - a heap buffer overflow followed by qsort() over OOB memory, causing a crash (DoS). Addressed by adding a capacity check + expand before the append loop, matching the existing pattern at all other candidate append logic. Ticket: #8866. --- src/detect.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/detect.c b/src/detect.c index 424d474950..6106d5fdc9 100644 --- a/src/detect.c +++ b/src/detect.c @@ -2654,6 +2654,13 @@ static void DetectRunTx(ThreadVars *tv, PrefilterPostRuleMatch(det_ctx, scratch->sgh, p, f); uint32_t prev_array_idx = array_idx; + + /* Check if there is room for the pmq results before appending them. */ + const uint32_t needed = array_idx + det_ctx->pmq.rule_id_array_cnt; + if (!(RuleMatchCandidateTxArrayHasSpace(det_ctx, needed))) { + RuleMatchCandidateTxArrayExpand(det_ctx, needed); + } + for (uint32_t j = 0; j < det_ctx->pmq.rule_id_array_cnt; j++) { const Signature *ts = de_ctx->sig_array[det_ctx->pmq.rule_id_array[j]]; if (ts->app_inspect != NULL) {