]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/address: limit recursion during parsing
authorVictor Julien <victor@inliniac.net>
Tue, 14 Apr 2020 06:01:49 +0000 (08:01 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 28 Apr 2020 12:07:54 +0000 (14:07 +0200)
Allow a max depth of 64.

Bug: #3586

src/detect-engine-address.c

index 2002fbc0420471ba82b5f567e380b2edb3cc34b0..f8e3004f01c58f18d4591450fb0fdfaf673da134 100644 (file)
@@ -735,7 +735,8 @@ static int DetectAddressSetup(DetectAddressHead *gh, const char *s)
  */
 static int DetectAddressParse2(const DetectEngineCtx *de_ctx,
         DetectAddressHead *gh, DetectAddressHead *ghn,
-        const char *s, int negate, ResolvedVariablesList *var_list)
+        const char *s, int negate, ResolvedVariablesList *var_list,
+        int recur)
 {
     size_t x = 0;
     size_t u = 0;
@@ -746,6 +747,12 @@ static int DetectAddressParse2(const DetectEngineCtx *de_ctx,
     const char *rule_var_address = NULL;
     char *temp_rule_var_address = NULL;
 
+    if (++recur > 64) {
+        SCLogError(SC_ERR_ADDRESS_ENGINE_GENERIC, "address block recursion "
+                "limit reached (max 64)");
+        goto error;
+    }
+
     SCLogDebug("s %s negate %s", s, negate ? "true" : "false");
 
     for (u = 0, x = 0; u < size && x < sizeof(address); u++) {
@@ -776,7 +783,7 @@ static int DetectAddressParse2(const DetectEngineCtx *de_ctx,
                     /* normal block */
                     SCLogDebug("normal block");
 
-                    if (DetectAddressParse2(de_ctx, gh, ghn, address, (negate + n_set) % 2, var_list) < 0)
+                    if (DetectAddressParse2(de_ctx, gh, ghn, address, (negate + n_set) % 2, var_list, recur) < 0)
                         goto error;
                 } else {
                     /* negated block
@@ -789,7 +796,7 @@ static int DetectAddressParse2(const DetectEngineCtx *de_ctx,
                     DetectAddressHead tmp_gh = { NULL, NULL };
                     DetectAddressHead tmp_ghn = { NULL, NULL };
 
-                    if (DetectAddressParse2(de_ctx, &tmp_gh, &tmp_ghn, address, 0, var_list) < 0) {
+                    if (DetectAddressParse2(de_ctx, &tmp_gh, &tmp_ghn, address, 0, var_list, recur) < 0) {
                         DetectAddressHeadCleanup(&tmp_gh);
                         DetectAddressHeadCleanup(&tmp_ghn);
                         goto error;
@@ -889,7 +896,7 @@ static int DetectAddressParse2(const DetectEngineCtx *de_ctx,
 
 
                 if (DetectAddressParse2(de_ctx, gh, ghn, temp_rule_var_address,
-                                    (negate + n_set) % 2, var_list) < 0)
+                                    (negate + n_set) % 2, var_list, recur) < 0)
                 {
                     if (temp_rule_var_address != rule_var_address)
                         SCFree(temp_rule_var_address);
@@ -957,7 +964,7 @@ static int DetectAddressParse2(const DetectEngineCtx *de_ctx,
                 }
 
                 if (DetectAddressParse2(de_ctx, gh, ghn, temp_rule_var_address,
-                                    (negate + n_set) % 2, var_list) < 0) {
+                                    (negate + n_set) % 2, var_list, recur) < 0) {
                     SCLogDebug("DetectAddressParse2 hates us");
                     if (temp_rule_var_address != rule_var_address)
                         SCFree(temp_rule_var_address);
@@ -1251,7 +1258,7 @@ int DetectAddressTestConfVars(void)
             goto error;
         }
 
-        int r = DetectAddressParse2(NULL, gh, ghn, seq_node->val, /* start with negate no */0, &var_list);
+        int r = DetectAddressParse2(NULL, gh, ghn, seq_node->val, /* start with negate no */0, &var_list, 0);
 
         CleanVariableResolveList(&var_list);
 
@@ -1410,7 +1417,7 @@ int DetectAddressParse(const DetectEngineCtx *de_ctx,
         return -1;
     }
 
-    int r = DetectAddressParse2(de_ctx, gh, ghn, str, /* start with negate no */0, NULL);
+    int r = DetectAddressParse2(de_ctx, gh, ghn, str, /* start with negate no */0, NULL, 0);
     if (r < 0) {
         SCLogDebug("DetectAddressParse2 returned %d", r);
         DetectAddressHeadFree(ghn);
@@ -2292,6 +2299,32 @@ static int AddressTestParse25(void)
     PASS;
 }
 
+/** \test recursion limit */
+static int AddressTestParse26(void)
+{
+    DetectAddressHead *gh = DetectAddressHeadInit();
+    FAIL_IF_NULL(gh);
+    /* exactly 64: should pass */
+    int r = DetectAddressParse(NULL, gh,
+            "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+            "1.2.3.4"
+            "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
+            );
+    FAIL_IF_NOT(r == 0);
+    DetectAddressHeadFree(gh);
+    gh = DetectAddressHeadInit();
+    FAIL_IF_NULL(gh);
+    /* exactly 65: should fail */
+    r = DetectAddressParse(NULL, gh,
+            "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
+            "1.2.3.4"
+            "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
+            );
+    FAIL_IF(r == 0);
+    DetectAddressHeadFree(gh);
+    PASS;
+}
+
 static int AddressTestParse27(void)
 {
     DetectAddress *dd = DetectAddressParseSingle("!192.168.0.1");
@@ -4828,6 +4861,7 @@ void DetectAddressTests(void)
     UtRegisterTest("AddressTestParse23", AddressTestParse23);
     UtRegisterTest("AddressTestParse24", AddressTestParse24);
     UtRegisterTest("AddressTestParse25", AddressTestParse25);
+    UtRegisterTest("AddressTestParse26", AddressTestParse26);
     UtRegisterTest("AddressTestParse27", AddressTestParse27);
     UtRegisterTest("AddressTestParse28", AddressTestParse28);
     UtRegisterTest("AddressTestParse29", AddressTestParse29);