]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: don't rescan when just distance is used
authorVictor Julien <victor@inliniac.net>
Sat, 4 Mar 2017 12:40:39 +0000 (13:40 +0100)
committerVictor Julien <victor@inliniac.net>
Mon, 1 May 2017 09:59:03 +0000 (11:59 +0200)
Content inspection optimization: when just distance is used without
within we don't need to search recursively.

E.g. content:"a"; content:"b"; distance:1; will scan the buffer for
'a' and when it finds 'a' it will scan the remainder for 'b'. Until
now, the failure to find 'b' would lead to looking for the next 'a'
and then for 'b' after that. However, we already inspected the
entire buffer for 'b', so we know this will fail.

src/detect-byte-extract.c
src/detect-content.h
src/detect-distance.c
src/detect-engine-content-inspection.c
src/detect-within.c
src/tests/detect-engine-content-inspection.c

index 0b0f4734777c9455c807073b686e6cbb5f5011fe..6a19310500685b0abb66497a19441f5d6b545d14 100644 (file)
@@ -2918,7 +2918,7 @@ static int DetectByteExtractTest48(void)
     if (strncmp((char *)cd->content, "four", cd->content_len) != 0 ||
         cd->flags != (DETECT_CONTENT_DISTANCE_BE |
                       DETECT_CONTENT_DISTANCE |
-                      DETECT_CONTENT_RELATIVE_NEXT) ||
+                      DETECT_CONTENT_DISTANCE_NEXT) ||
         cd->distance != bed1->local_id ||
         cd->depth != 0 ||
         cd->offset != 0) {
@@ -3147,7 +3147,7 @@ static int DetectByteExtractTest50(void)
     if (strncmp((char *)cd->content, "four", cd->content_len) != 0 ||
         cd->flags != (DETECT_CONTENT_WITHIN_BE |
                       DETECT_CONTENT_WITHIN|
-                      DETECT_CONTENT_RELATIVE_NEXT) ||
+                      DETECT_CONTENT_WITHIN_NEXT) ||
         cd->within != bed1->local_id ||
         cd->depth != 0 ||
         cd->offset != 0 ||
index 70d17961e217bb0424ce2f0f3e30f02c03e2884c..2182b1bacd00ced507bb481257dacbbcfa6392dc 100644 (file)
@@ -39,8 +39,7 @@
 /** content is negated */
 #define DETECT_CONTENT_NEGATED           BIT_U32(9)
 
-/** a relative match to this content is next, used in matching phase */
-#define DETECT_CONTENT_RELATIVE_NEXT     BIT_U32(10)
+// bit 10 unused
 
 /* BE - byte extract */
 #define DETECT_CONTENT_OFFSET_BE         BIT_U32(11)
  * the inspection phase */
 #define DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED BIT_U32(16)
 
+#define DETECT_CONTENT_WITHIN_NEXT      BIT_U32(17)
+#define DETECT_CONTENT_DISTANCE_NEXT    BIT_U32(18)
+/** a relative match to this content is next, used in matching phase */
+#define DETECT_CONTENT_RELATIVE_NEXT    (DETECT_CONTENT_WITHIN_NEXT|DETECT_CONTENT_DISTANCE_NEXT)
 
 #define DETECT_CONTENT_IS_SINGLE(c) (!( ((c)->flags & DETECT_CONTENT_DISTANCE) || \
                                         ((c)->flags & DETECT_CONTENT_WITHIN) || \
index 10f65284779ff03ae6eb0e3e95718e716dbdb039..869a1450264f3e92d4d01e42dfecc8b33e5c74e6 100644 (file)
@@ -142,7 +142,11 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
                        "only content");
             goto end;
         }
-        prev_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
+        if ((cd->flags & DETECT_CONTENT_NEGATED) == 0) {
+            prev_cd->flags |= DETECT_CONTENT_DISTANCE_NEXT;
+        } else {
+            prev_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
+        }
     } else if (prev_pm->type == DETECT_PCRE) {
         DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx;
         pd->flags |= DETECT_PCRE_RELATIVE_NEXT;
index 58131d02d8d5def8e2410dfbbfb5d1763ecf5124..bea5157e53fae38035bcf17ec1340d5ef00f84d6 100644 (file)
@@ -340,7 +340,7 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx
                 }
 
                 /* no match and no reason to look for another instance */
-                if ((cd->flags & DETECT_CONTENT_RELATIVE_NEXT) == 0) {
+                if ((cd->flags & DETECT_CONTENT_WITHIN_NEXT) == 0) {
                     SCLogDebug("'next sm' does not depend on me, so we can give up");
                     det_ctx->discontinue_matching = 1;
                     goto no_match;
index b7921a3138a2e9fb3cec202ae0737966e197048a..772fb039d72f6a9b9a509b7c66e8edb6ced091e3 100644 (file)
@@ -152,7 +152,7 @@ static int DetectWithinSetup(DetectEngineCtx *de_ctx, Signature *s, char *within
                        "only content");
             goto end;
         }
-        prev_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
+        prev_cd->flags |= DETECT_CONTENT_WITHIN_NEXT;
     } else if (prev_pm->type == DETECT_PCRE) {
         DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx;
         pd->flags |= DETECT_PCRE_RELATIVE_NEXT;
index eaf52a8305c9ee943f58b898f7ebdd745c5a8aac..b633e255f26abf32365ff913f065c397649cbce6 100644 (file)
@@ -83,7 +83,7 @@ static int DetectEngineContentInspectionTest03(void) {
     TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; content:\"d\";", false, 3);
 
     TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0;", true, 3);
-    TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; distance:0; content:\"d\"; distance:0;", false, 6); // TODO should be 3?
+    TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; distance:0; content:\"d\"; distance:0;", false, 3);
 
     TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; distance:0; within:1; content:\"d\"; distance:0; within:1;", false, 5);
 
@@ -155,15 +155,15 @@ static int DetectEngineContentInspectionTest07(void) {
     TEST_RUN("abcabcabcabcabcabcabcabcabcabcd", 31, "content:\"a\"; content:\"b\"; within:1; distance:0; content:\"c\"; distance:0; within:1; content:\"d\"; within:1; distance:0; ", true, 31);
     TEST_RUN("abcabcabcabcabcabcabcabcabcabcx", 31, "content:\"a\"; content:\"b\"; within:1; distance:0; content:\"c\"; distance:0; within:1; content:\"d\"; within:1; distance:0; ", false, 31);
 
-    TEST_RUN("abcabcabcabcabcabcabcabcabcabcx", 31, "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; ", false, 286); // TODO should be 4?
-    TEST_RUN("abcabcabcabcabcabcabcabcabcabcx", 31, "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; pcre:\"/^d/R\"; ", false, 286); // TODO should be 4?
-    TEST_RUN("abcabcabcabcabcabcabcabcabcabcx", 31, "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; isdataat:!1,relative; ", false, 286); // TODO should be 4?
+    TEST_RUN("abcabcabcabcabcabcabcabcabcabcx", 31, "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; ", false, 4);
+    TEST_RUN("abcabcabcabcabcabcabcabcabcabcx", 31, "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; pcre:\"/^d/R\"; ", false, 13);
+    TEST_RUN("abcabcabcabcabcabcabcabcabcabcx", 31, "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; isdataat:!1,relative; ", false, 13); // TODO should be 4?
     TEST_RUN("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdx", 41,
-            "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; content:\"e\"; distance:0; ", false, 1001); // TODO should be 5?
+            "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; content:\"e\"; distance:0; ", false, 5);
     TEST_RUN("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdx", 41,
-            "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; pcre:\"/^e/R\"; ", false, 1001); // TODO should be 5?
+            "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; pcre:\"/^e/R\"; ", false, 14); // TODO should be 5?
     TEST_RUN("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdx", 41,
-            "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; isdataat:!1,relative; ", false, 1001); // TODO should be 5?
+            "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; isdataat:!1,relative; ", false, 14); // TODO should be 5?
 
     TEST_RUN("abcabcabcabcabcabcabcabcabcabcd", 31, "content:\"a\"; content:\"b\"; within:1; distance:0; content:\"c\"; distance:0; within:1; pcre:\"/d/\";", true, 4);
     TEST_RUN("abcabcabcabcabcabcabcabcabcabcd", 31, "content:\"a\"; content:\"b\"; within:1; distance:0; content:\"c\"; distance:0; within:1; pcre:\"/d/R\";", true, 4);
@@ -175,6 +175,18 @@ static int DetectEngineContentInspectionTest07(void) {
     TEST_FOOTER;
 }
 
+/** \test mix in negation */
+static int DetectEngineContentInspectionTest08(void) {
+    TEST_HEADER;
+    TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; content:!\"d\";", true, 3);
+    TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; content:!\"c\";", false, 3);
+
+    TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; distance:0; within:1; content:!\"a\"; distance:0; within:1;", true, 5);
+    TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; distance:0; within:1; content:!\"a\"; distance:0; ", true, 5);
+
+    TEST_FOOTER;
+}
+
 void DetectEngineContentInspectionRegisterTests(void)
 {
     UtRegisterTest("DetectEngineContentInspectionTest01",
@@ -191,6 +203,8 @@ void DetectEngineContentInspectionRegisterTests(void)
                    DetectEngineContentInspectionTest06);
     UtRegisterTest("DetectEngineContentInspectionTest07",
                    DetectEngineContentInspectionTest07);
+    UtRegisterTest("DetectEngineContentInspectionTest08",
+                   DetectEngineContentInspectionTest08);
 }
 
 #undef TEST_HEADER