]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/bsize: Validate bsize values after parsing 8165/head
authorJeff Lucovsky <jlucovsky@oisf.net>
Sun, 16 Oct 2022 14:13:19 +0000 (10:13 -0400)
committerVictor Julien <vjulien@oisf.net>
Thu, 10 Nov 2022 13:42:44 +0000 (15:42 +0200)
Issue: 2982

This commit moves bsize validation with respect to content matches to
the post-parse validation stage. This allows bsize to consider all
content-related values, including those that follow the bsize keyword.

src/detect-bsize.c
src/detect-bsize.h
src/detect-parse.c
src/tests/detect-bsize.c

index c4719632eda5d2dd333ed2e75a60e0ff34673c41..8e4405073fe686f3d30a8b171f112b9aa4e1d367 100644 (file)
 /*prototypes*/
 static int DetectBsizeSetup (DetectEngineCtx *, Signature *, const char *);
 static void DetectBsizeFree (DetectEngineCtx *, void *);
+static int SigParseGetMaxBsize(DetectU64Data *bsz);
 #ifdef UNITTESTS
 static void DetectBsizeRegisterTests (void);
 #endif
 
+bool DetectBsizeValidateContentCallback(Signature *s, int list)
+{
+    int bsize = -1;
+    DetectU64Data *bsz;
+    for (const SigMatch *sm = s->init_data->smlists[list]; sm != NULL; sm = sm->next) {
+        if (sm->type == DETECT_BSIZE) {
+            bsz = (DetectU64Data *)sm->ctx;
+            bsize = SigParseGetMaxBsize(bsz);
+            break;
+        }
+    }
+
+    if (bsize == -1) {
+        return true;
+    }
+
+    uint64_t needed;
+    if (bsize >= 0) {
+        int len, offset;
+        SigParseRequiredContentSize(s, bsize, list, &len, &offset);
+        SCLogDebug("bsize: %d; len: %d; offset: %d [%s]", bsize, len, offset, s->sig_str);
+        needed = len;
+        if (len > bsize) {
+            goto value_error;
+        }
+        if ((len + offset) > bsize) {
+            needed += offset;
+            goto value_error;
+        }
+    }
+
+    return true;
+value_error:
+    if (bsz->mode == DETECT_UINT_RA) {
+        SCLogError(SC_ERR_INVALID_SIGNATURE,
+                "signature can't match as required content length %" PRIu64
+                " exceeds bsize range: %" PRIu64 "-%" PRIu64,
+                needed, bsz->arg1, bsz->arg2);
+    } else {
+        SCLogError(SC_ERR_INVALID_SIGNATURE,
+                "signature can't match as required content length %" PRIu64 " exceeds bsize value: "
+                "%" PRIu64,
+                needed, bsz->arg1);
+    }
+    return false;
+}
+
 /**
  * \brief Registration function for bsize: keyword
  */
@@ -61,8 +109,6 @@ void DetectBsizeRegister(void)
 #endif
 }
 
-static int SigParseGetMaxBsize(DetectU64Data *bsz);
-
 /** \brief bsize match function
  *
  *  \param ctx match ctx
@@ -167,23 +213,6 @@ static int DetectBsizeSetup (DetectEngineCtx *de_ctx, Signature *s, const char *
     if (bsz == NULL)
         goto error;
 
-    const int bsize = SigParseGetMaxBsize(bsz);
-
-    uint64_t needed;
-    if (bsize >= 0) {
-        int len, offset;
-        SigParseRequiredContentSize(s, bsize, list, &len, &offset);
-        SCLogDebug("bsize: %d; len: %d; offset: %d [%s]", bsize, len, offset, s->sig_str);
-        needed = len;
-        if (len > bsize) {
-            goto value_error;
-        }
-        if ((len + offset) > bsize) {
-            needed += offset;
-            goto value_error;
-        }
-    }
-
     sm = SigMatchAlloc();
     if (sm == NULL)
         goto error;
@@ -194,19 +223,6 @@ static int DetectBsizeSetup (DetectEngineCtx *de_ctx, Signature *s, const char *
 
     SCReturnInt(0);
 
-value_error:
-    if (bsz->mode == DETECT_UINT_RA) {
-        SCLogError(SC_ERR_INVALID_SIGNATURE,
-                "signature can't match as required content length %" PRIu64
-                " exceeds bsize range: %" PRIu64 "-%" PRIu64,
-                needed, bsz->arg1, bsz->arg2);
-    } else {
-        SCLogError(SC_ERR_INVALID_SIGNATURE,
-                "signature can't match as required content length %" PRIu64 " exceeds bsize value: "
-                "%" PRIu64,
-                needed, bsz->arg1);
-    }
-
 error:
     DetectBsizeFree(de_ctx, bsz);
     SCReturnInt(-1);
index ad51b62cf9e2680e8b58d9dda2d1a10c38a18e21..1535c6fdb2715f52bddeed93f1a40d7ea649c759 100644 (file)
@@ -26,5 +26,6 @@
 
 void DetectBsizeRegister(void);
 int DetectBsizeMatch(const SigMatchCtx *ctx, const uint64_t buffer_size, bool eof);
+bool DetectBsizeValidateContentCallback(Signature *s, int list);
 
 #endif /* __DETECT_URILEN_H__ */
index b6dbc8bb348d56a24ae076998e7e308621887849..061265cffeda9ac5086d503c4bc388dcc25ebe76 100644 (file)
@@ -34,6 +34,7 @@
 #include "detect-engine-build.h"
 
 #include "detect-content.h"
+#include "detect-bsize.h"
 #include "detect-pcre.h"
 #include "detect-uricontent.h"
 #include "detect-reference.h"
@@ -1727,6 +1728,10 @@ static int SigValidate(DetectEngineCtx *de_ctx, Signature *s)
             if (!DetectEngineBufferRunValidateCallback(de_ctx, x, s, &de_ctx->sigerror)) {
                 SCReturnInt(0);
             }
+
+            if (!DetectBsizeValidateContentCallback(s, x)) {
+                SCReturnInt(0);
+            }
         }
     }
 
index bf6a192a8ded5545dbc543ac9d78b407ad58befb..2fcd656589907f9a9d92650ffec5195705cbd595 100644 (file)
@@ -156,6 +156,8 @@ static int DetectBsizeSigTest01(void)
               "sid:17;)");
     TEST_FAIL("alert http any any -> any any (http.uri; content:\"abc\"; offset:65535; bsize:3; "
               "sid:18;)");
+    TEST_FAIL("alert http any any -> any any (http.user_agent; content:\"Suricata-UA\"; bsize:11; "
+              "content:!\"abc\"; distance:2; within:3;  sid: 19;)");
     PASS;
 }