]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/bsize: Semantic validation of bsize values
authorJeff Lucovsky <jeff@lucovsky.org>
Thu, 27 Jan 2022 15:23:55 +0000 (10:23 -0500)
committerVictor Julien <vjulien@oisf.net>
Thu, 10 Nov 2022 13:42:44 +0000 (15:42 +0200)
This commit adds validation of the bsize value(s) with the available
buffer size. Signatures are flagged if the bsize and buffer size are
incompatible.

Issue: 3682

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

index 6cb63a6e00faece5df8779acffd476eb65497d76..c4719632eda5d2dd333ed2e75a60e0ff34673c41 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017-2020 Open Information Security Foundation
+/* Copyright (C) 2017-2022 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
@@ -61,6 +61,8 @@ void DetectBsizeRegister(void)
 #endif
 }
 
+static int SigParseGetMaxBsize(DetectU64Data *bsz);
+
 /** \brief bsize match function
  *
  *  \param ctx match ctx
@@ -124,12 +126,27 @@ static DetectU64Data *DetectBsizeParse(const char *str)
     return DetectU64Parse(str);
 }
 
+static int SigParseGetMaxBsize(DetectU64Data *bsz)
+{
+    switch (bsz->mode) {
+        case DETECT_UINT_LT:
+        case DETECT_UINT_EQ:
+            return bsz->arg1;
+        case DETECT_UINT_RA:
+            return bsz->arg2;
+        case DETECT_UINT_GT:
+        default:
+            SCReturnInt(-2);
+    }
+    SCReturnInt(-1);
+}
+
 /**
  * \brief this function is used to parse bsize data into the current signature
  *
  * \param de_ctx pointer to the Detection Engine Context
  * \param s pointer to the Current Signature
- * \param bsizestr pointer to the user provided bsize options
+ * \param sizestr pointer to the user provided bsize options
  *
  * \retval 0 on Success
  * \retval -1 on Failure
@@ -149,6 +166,24 @@ static int DetectBsizeSetup (DetectEngineCtx *de_ctx, Signature *s, const char *
     DetectU64Data *bsz = DetectBsizeParse(sizestr);
     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;
@@ -159,6 +194,19 @@ 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 524d6d192eefc89cb3c02b443226db76be2e7cbd..bf6a192a8ded5545dbc543ac9d78b407ad58befb 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017-2020 Open Information Security Foundation
+/* Copyright (C) 2017-2022 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
@@ -118,41 +118,42 @@ static int DetectBsizeTest04(void)
 
 static int DetectBsizeSigTest01(void)
 {
-#if 0
     TEST_OK("alert http any any -> any any (http_request_line; bsize:10; sid:1;)");
     TEST_OK("alert http any any -> any any (file_data; bsize:>1000; sid:2;)");
 
-    TEST_FAIL("alert tcp any any -> any any (content:\"abc\"; bsize:10; sid:3;)");
-    TEST_FAIL("alert http any any -> any any (content:\"GET\"; http_method; bsize:10; sid:4;)");
-    TEST_FAIL("alert http any any -> any any (http_request_line; content:\"GET\"; bsize:<10>; sid:5;)");
-
     /* bsize validation with buffer */
     TEST_OK("alert http any any -> any any (http.uri; content:\"/index.php\"; bsize:>1024; "
             "sid:6;)");
-    TEST_OK("alert http any any -> any any (http.uri; content:\"abdcef\"; content: \"g\"; bsize:1; "
-            "sid:7;)");
-    TEST_OK("alert http any any -> any any (http.uri; content:\"abdcef\"; content: \"g\"; bsize:4; "
-            "sid:8;)");
     TEST_OK("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:<20; "
             " sid:9;)");
     TEST_OK("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:15<>25; "
             "sid:10;)");
+    TEST_OK("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:10<>15; "
+            "sid:13;)");
+
+    TEST_FAIL("alert tcp any any -> any any (content:\"abc\"; bsize:10; sid:3;)");
+    TEST_FAIL("alert http any any -> any any (content:\"GET\"; http_method; bsize:10; sid:4;)");
+    TEST_FAIL("alert http any any -> any any (http_request_line; content:\"GET\"; bsize:<10>; "
+              "sid:5;)");
+
     TEST_FAIL("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:2; "
               "sid:11;)");
     TEST_FAIL("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:<13; "
               "sid:12;)");
-    TEST_OK("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:10<>15; "
-              "sid:13;)");
+    TEST_FAIL(
+            "alert http any any -> any any (http.uri; content:\"abcdef\"; content: \"g\"; bsize:1; "
+            "sid:7;)");
+    TEST_FAIL(
+            "alert http any any -> any any (http.uri; content:\"abcdef\"; content: \"g\"; bsize:4; "
+            "sid:8;)");
     TEST_FAIL("alert http any any -> any any (http.uri; content:\"abcdefghi123456\"; offset:12; "
               "bsize:3; sid:14;)");
     TEST_FAIL("alert http any any -> any any (http.uri; content:\"abc\"; offset:3; depth:3; "
               "bsize:3; sid:15;)");
-    TEST_FAIL("alert http any any -> any any (http.uri; content:\"abdcef\"; content: \"gh\"; "
+    TEST_FAIL("alert http any any -> any any (http.uri; content:\"abcdef\"; content: \"gh\"; "
               "bsize:1; sid:16;)");
     TEST_FAIL("alert http any any -> any any (http.uri; content:\"abc\"; offset:3; bsize:3; "
               "sid:17;)");
-
-#endif
     TEST_FAIL("alert http any any -> any any (http.uri; content:\"abc\"; offset:65535; bsize:3; "
               "sid:18;)");
     PASS;