]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/port: limit recursion in port parsing
authorVictor Julien <victor@inliniac.net>
Tue, 14 Apr 2020 09:00:39 +0000 (11:00 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 28 Apr 2020 12:07:54 +0000 (14:07 +0200)
Bug: #3586

src/detect-engine-port.c

index d7409c4129bb9d37ea484863b6a1950b6b695dc7..f0e768b78b6b9ba7919cd5034fb73eedeacb8574 100644 (file)
@@ -831,7 +831,7 @@ error:
 static int DetectPortParseDo(const DetectEngineCtx *de_ctx,
                              DetectPort **head, DetectPort **nhead,
                              const char *s, int negate,
-                             ResolvedVariablesList *var_list)
+                             ResolvedVariablesList *var_list, int recur)
 {
     size_t u = 0;
     size_t x = 0;
@@ -843,6 +843,12 @@ static int DetectPortParseDo(const DetectEngineCtx *de_ctx,
     const char *rule_var_port = NULL;
     int r = 0;
 
+    if (recur++ > 64) {
+        SCLogError(SC_ERR_PORT_ENGINE_GENERIC, "port block recursion "
+                "limit reached (max 64)");
+        goto error;
+    }
+
     SCLogDebug("head %p, *head %p, negate %d", head, *head, negate);
 
     for (u = 0, x = 0; u < size && x < sizeof(address); u++) {
@@ -871,7 +877,8 @@ static int DetectPortParseDo(const DetectEngineCtx *de_ctx,
                 SCLogDebug("Parsed port from DetectPortParseDo - %s", address);
                 x = 0;
 
-                r = DetectPortParseDo(de_ctx, head, nhead, address, negate? negate: n_set, var_list);
+                r = DetectPortParseDo(de_ctx, head, nhead, address,
+                        negate? negate: n_set, var_list, recur);
                 if (r == -1)
                     goto error;
 
@@ -912,7 +919,7 @@ static int DetectPortParseDo(const DetectEngineCtx *de_ctx,
                 }
                 temp_rule_var_port = alloc_rule_var_port;
                 r = DetectPortParseDo(de_ctx, head, nhead, temp_rule_var_port,
-                                  (negate + n_set) % 2, var_list);//negate? negate: n_set);
+                                  (negate + n_set) % 2, var_list, recur);
                 if (r == -1) {
                     SCFree(alloc_rule_var_port);
                     goto error;
@@ -982,7 +989,7 @@ static int DetectPortParseDo(const DetectEngineCtx *de_ctx,
                 }
                 temp_rule_var_port = alloc_rule_var_port;
                 r = DetectPortParseDo(de_ctx, head, nhead, temp_rule_var_port,
-                                  (negate + n_set) % 2, var_list);
+                                  (negate + n_set) % 2, var_list, recur);
                 SCFree(alloc_rule_var_port);
                 if (r == -1)
                     goto error;
@@ -1184,7 +1191,8 @@ int DetectPortTestConfVars(void)
             goto error;
         }
 
-        int r = DetectPortParseDo(NULL, &gh, &ghn, seq_node->val, /* start with negate no */0, &var_list);
+        int r = DetectPortParseDo(NULL, &gh, &ghn, seq_node->val,
+                /* start with negate no */0, &var_list, 0);
 
         CleanVariableResolveList(&var_list);
 
@@ -1238,7 +1246,7 @@ int DetectPortParse(const DetectEngineCtx *de_ctx,
     DetectPort *nhead = NULL;
 
     int r = DetectPortParseDo(de_ctx, head, &nhead, str,
-            /* start with negate no */ 0, NULL);
+            /* start with negate no */ 0, NULL, 0);
     if (r < 0)
         goto error;
 
@@ -1737,6 +1745,26 @@ static int PortTestParse15 (void)
     PASS;
 }
 
+static int PortTestParse16 (void)
+{
+    DetectPort *dd = NULL;
+    int r = DetectPortParse(NULL,&dd,"\
+[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\
+1:65535\
+]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\
+");
+    FAIL_IF_NOT(r == 0);
+    DetectPortFree(NULL, dd);
+    dd = NULL;
+    r = DetectPortParse(NULL,&dd,"\
+[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\
+1:65535\
+]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]\
+");
+    FAIL_IF(r == 0);
+    PASS;
+}
+
 /**
  * \test Test general functions
  */
@@ -2424,7 +2452,7 @@ static int PortTestMatchDoubleNegation(void)
     int result = 0;
     DetectPort *head = NULL, *nhead = NULL;
 
-    if (DetectPortParseDo(NULL, &head, &nhead, "![!80]", 0, NULL) == -1)
+    if (DetectPortParseDo(NULL, &head, &nhead, "![!80]", 0, NULL, 0) == -1)
         return result;
 
     result = (head != NULL);
@@ -2449,6 +2477,7 @@ void DetectPortTests(void)
     UtRegisterTest("PortTestParse13", PortTestParse13);
     UtRegisterTest("PortTestParse14", PortTestParse14);
     UtRegisterTest("PortTestParse15", PortTestParse15);
+    UtRegisterTest("PortTestParse16", PortTestParse16);
     UtRegisterTest("PortTestFunctions01", PortTestFunctions01);
     UtRegisterTest("PortTestFunctions02", PortTestFunctions02);
     UtRegisterTest("PortTestFunctions03", PortTestFunctions03);