]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: fix FNs in case of too many prefilter engines 6415/head
authorVictor Julien <victor@inliniac.net>
Tue, 28 Sep 2021 10:28:54 +0000 (12:28 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 28 Sep 2021 12:18:22 +0000 (14:18 +0200)
Fix FNs in case of too many prefilter engines. A transaction was tracking
which engines have run using a u64 bit array. The engines 'local_id' was
used to set and check this bit. However the bit checking code didn't
handle int types correctly, leading to an incorrect left shift result of
a u32 to a u64 bit value.

This commit addresses that by fixing the int handling.

This is only a partial fix however. It's not hard to craft a ruleset that
exceeds the 63-bit space available. A more complete fix is in:

932cf0b6a6ad ("detect: track prefilter by progress, not engine")

However this seems like a too high risk change for a backport into
5.0.

This patch does issue a warning if the condition is detected at start
up, and `-T` does error out on it.

Bug: #4688.

src/detect-engine-prefilter.c

index f0f3e68b7b8d7ae5c32a9acc6751f8739625d8d6..98477243ec928902309800d47f118f3701678b05 100644 (file)
@@ -108,7 +108,7 @@ void DetectRunPrefilterTx(DetectEngineThreadCtx *det_ctx,
         if (engine->tx_min_progress > tx->tx_progress)
             goto next;
         if (tx->tx_progress > engine->tx_min_progress) {
-            if (tx->prefilter_flags & (1<<(engine->local_id))) {
+            if (tx->prefilter_flags & BIT_U64(engine->local_id)) {
                 goto next;
             }
         }
@@ -119,7 +119,7 @@ void DetectRunPrefilterTx(DetectEngineThreadCtx *det_ctx,
         PREFILTER_PROFILING_END(det_ctx, engine->gid);
 
         if (tx->tx_progress > engine->tx_min_progress) {
-            tx->prefilter_flags |= (1<<(engine->local_id));
+            tx->prefilter_flags |= BIT_U64(engine->local_id);
         }
     next:
         if (engine->is_last)
@@ -447,6 +447,17 @@ void PrefilterSetupRuleGroup(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
             e++;
         }
         SCLogDebug("sgh %p max local_id %u", sgh, local_id);
+
+        /* max assigned id can be 62 (63 is reserved) */
+        if (local_id >= 63) {
+            if (de_ctx->failure_fatal) {
+                FatalError(SC_ERR_DETECT_PREPARE, "max number of prefilter engines exceeded (%u >= 62). "
+                        "Risk of False Negatives. See ticket #4688.", local_id - 1);
+            } else {
+                SCLogWarning(SC_ERR_DETECT_PREPARE, "max number of prefilter engines exceeded (%u >= 62). "
+                        "Risk of False Negatives. See ticket #4688.", local_id - 1);
+            }
+        }
     }
 }