From d59f95625fe2bcc472fe8cdbbf89b0ebcd14d666 Mon Sep 17 00:00:00 2001 From: Anoop Saldanha Date: Wed, 17 Feb 2010 19:18:52 +0530 Subject: [PATCH] Fix for bug 1. Fixes the conflict between distance and within for a content keyword --- src/detect-content.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ src/detect-content.h | 2 + src/detect-distance.c | 3 ++ src/detect-within.c | 3 ++ 4 files changed, 73 insertions(+), 0 deletions(-) diff --git a/src/detect-content.c b/src/detect-content.c index dc99dbb..ecd8a0a 100644 --- a/src/detect-content.c +++ b/src/detect-content.c @@ -1385,6 +1385,42 @@ int DetectContentPropagateModifiers(SigMatch *first_sm) } /** + * \brief Validates the modifiers for a "content" keyword. + * + * \param m Pointer to the SigMatch corresponding to the content keyword that + * has to be checked. + * + * \retval 1 If all the modifiers and their arguments agree with each other. + * \retval 0 If some modifier(s) hold values that don't agree with others. + */ +int DetectContentValidateModifiers(SigMatch *m) +{ + DetectContentData *cd = (DetectContentData *)m->ctx; + int result = 0; + + /* if the content keyword has both the distance and within keywords, check + * that the values specified for these keywords don't conflict with each + * other */ + if ((cd->flags & DETECT_CONTENT_WITHIN) && + (cd->flags & DETECT_CONTENT_DISTANCE)) { + if (((int)cd->within - (int)cd->distance) < (int)cd->content_len) { + SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid signature. The " + "distance and the within do not agree with each other. " + "Invalidating signature"); + + goto end; + } + } + + /* if we have passed all validations successfully, we return a success */ + result = 1; + + end: + return result; +} + + +/** * \brief Function to setup a content pattern. Patterns that doesn't fit the * current max_pattern_length, are splitted into multiple chunks in independent * DetectContentData structures with it's own modifiers. Each modifier must be @@ -3063,6 +3099,32 @@ static int SigTest75TestNegatedContent(void) return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"USER\"; content:\"!PASS\"; sid:1;)", (uint8_t *)"USER !PASS"); } +int DetectContentTestDistanceWithinConflict(void) +{ + Signature *s = NULL; + int result = 0; + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->mpm_matcher = MPM_B2G; + char *sigstr = "alert tcp any any -> any any (msg:\"distance within conflict test\"; " + "content:one; content:two; distance:1; within:3; sid:1;)"; + + s = SigInit(de_ctx, sigstr); + if (s != NULL) + goto end; + + result = 1; + +end: + SigCleanSignatures(de_ctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + return result; +} + #endif /* UNITTESTS */ /** @@ -3147,5 +3209,8 @@ void DetectContentRegisterTests(void) UtRegisterTest("SigTest74TestNegatedContent", SigTest74TestNegatedContent, 1); UtRegisterTest("SigTest75TestNegatedContent", SigTest75TestNegatedContent, 1); + UtRegisterTest("DetectContentTestDistanceWithinConflict", + DetectContentTestDistanceWithinConflict, 1); + #endif /* UNITTESTS */ } diff --git a/src/detect-content.h b/src/detect-content.h index 63f8208..bc764c8 100644 --- a/src/detect-content.h +++ b/src/detect-content.h @@ -79,6 +79,8 @@ int DetectContentPropagateOffset(SigMatch *); int DetectContentPropagateDistance(SigMatch *); int DetectContentPropagateIsdataat(SigMatch *); +int DetectContentValidateModifiers(SigMatch *); + /** This shall not be called from outside detect-content.c (used internally)*/ int DetectContentPropagateModifiers(SigMatch *); diff --git a/src/detect-distance.c b/src/detect-distance.c index cb2529b..d00db65 100644 --- a/src/detect-distance.c +++ b/src/detect-distance.c @@ -60,6 +60,9 @@ int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, cha cd->distance = strtol(str, NULL, 10); cd->flags |= DETECT_CONTENT_DISTANCE; + if (!DetectContentValidateModifiers(pm)) + goto error; + /** Propagate the modifiers through the first chunk * (SigMatch) if we're dealing with chunks */ if (cd->flags & DETECT_CONTENT_IS_CHUNK) diff --git a/src/detect-within.c b/src/detect-within.c index 05ffd9b..a0a2b6e 100644 --- a/src/detect-within.c +++ b/src/detect-within.c @@ -62,6 +62,9 @@ int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char cd->within = strtol(str, NULL, 10); cd->flags |= DETECT_CONTENT_WITHIN; + if (!DetectContentValidateModifiers(pm)) + goto error; + /** Propagate the modifiers through the first chunk * (SigMatch) if we're dealing with chunks */ if (cd->flags & DETECT_CONTENT_IS_CHUNK) -- 1.5.5