From 2911656d6c11e8ef64a55ce64216382cd22151fe Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Wed, 20 Dec 2023 21:40:47 +0100 Subject: [PATCH] detect/content: fix offset for negative distance Fix offset calculation on sigs with negative distance. Can lead to FN in certain cases. Bug: #6661. --- src/detect-content.c | 19 +++++++++++++++---- src/tests/detect-engine-content-inspection.c | 13 +++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/detect-content.c b/src/detect-content.c index ebe28a1b04..944172702d 100644 --- a/src/detect-content.c +++ b/src/detect-content.c @@ -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) { diff --git a/src/tests/detect-engine-content-inspection.c b/src/tests/detect-engine-content-inspection.c index 4430422a83..780ae6d4c6 100644 --- a/src/tests/detect-engine-content-inspection.c +++ b/src/tests/detect-engine-content-inspection.c @@ -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