]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/content: fix offset for negative distance
authorVictor Julien <vjulien@oisf.net>
Wed, 20 Dec 2023 20:40:47 +0000 (21:40 +0100)
committerVictor Julien <victor@inliniac.net>
Mon, 8 Jan 2024 19:23:28 +0000 (20:23 +0100)
Fix offset calculation on sigs with negative distance. Can lead to FN
in certain cases.

Bug: #6661.

src/detect-content.c
src/tests/detect-engine-content-inspection.c

index ebe28a1b04fab2dc92a4ce7be6e979be121c261c..944172702d9299e1b6417e8f5b1d1aa3b508d6e7 100644 (file)
@@ -571,10 +571,21 @@ static void PropagateLimits(Signature *s, SigMatch *sm_head)
                 SCLogDebug("stored: offset %u depth %u offset_plus_pat %u "
                            "has_active_depth_chain %s",
                         offset, depth, offset_plus_pat, has_active_depth_chain ? "true" : "false");
-                if (cd->flags & DETECT_CONTENT_DISTANCE && cd->distance >= 0) {
-                    VALIDATE((uint32_t)offset_plus_pat + cd->distance <= UINT16_MAX);
-                    offset = cd->offset = (uint16_t)(offset_plus_pat + cd->distance);
-                    SCLogDebug("updated content to have offset %u", cd->offset);
+                if (cd->flags & DETECT_CONTENT_DISTANCE) {
+                    if (cd->distance >= 0) {
+                        VALIDATE((uint32_t)offset_plus_pat + cd->distance <= UINT16_MAX);
+                        offset = cd->offset = (uint16_t)(offset_plus_pat + cd->distance);
+                        SCLogDebug("distance %d: updated content to have offset %u", cd->distance,
+                                cd->offset);
+                    } else {
+                        if (abs(cd->distance) > offset_plus_pat)
+                            offset = cd->offset = 0;
+                        else
+                            offset = cd->offset = (uint16_t)(offset_plus_pat + cd->distance);
+                        offset_plus_pat = offset + cd->content_len;
+                        SCLogDebug("distance %d: updated content to have offset %u", cd->distance,
+                                cd->offset);
+                    }
                 }
                 if (has_active_depth_chain) {
                     if (offset_plus_pat && cd->flags & DETECT_CONTENT_WITHIN && cd->within >= 0) {
index 4430422a83daae24a0fa1bec2140fea87e95f07c..780ae6d4c614bf7ade1fea5ad731e4a961ae5739 100644 (file)
@@ -303,6 +303,17 @@ static int DetectEngineContentInspectionTest14(void)
     TEST_FOOTER;
 }
 
+/** \brief negative distance */
+static int DetectEngineContentInspectionTest17(void)
+{
+    TEST_HEADER;
+    TEST_RUN("aaabbbcccdddee", 14,
+            "content:\"aaa\"; content:\"ee\"; within:2; distance:9; content:\"bbb\"; within:3; "
+            "distance:-11; content:\"ccc\"; within:3; distance:0;",
+            true, 4);
+    TEST_FOOTER;
+}
+
 void DetectEngineContentInspectionRegisterTests(void)
 {
     UtRegisterTest("DetectEngineContentInspectionTest01",
@@ -333,6 +344,8 @@ void DetectEngineContentInspectionRegisterTests(void)
                    DetectEngineContentInspectionTest13);
     UtRegisterTest("DetectEngineContentInspectionTest14 byte_test negative offset",
             DetectEngineContentInspectionTest14);
+    UtRegisterTest("DetectEngineContentInspectionTest17 negative distance",
+            DetectEngineContentInspectionTest17);
 }
 
 #undef TEST_HEADER