From: Victor Julien Date: Sat, 19 Sep 2015 18:53:26 +0000 (+0200) Subject: mpm: redo uri maxlen logic X-Git-Tag: suricata-3.0RC1~141 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e529ebb50edbed9fe6aa6d1a5ad66bbf6bc17948;p=thirdparty%2Fsuricata.git mpm: redo uri maxlen logic The mpm_uricontent_maxlen logic was meant to track the shortest possible pattern in the MPM of a SGH. So a minlen more than a maxlen. This patch replaces the complicated tracking logic by a simpler scheme. When the SGH's are finalize, the minlen is calculated. It also fixes a small corner case where the calculated "maxlen" could be wrong. This would require a smaller pattern in a rule to be forced as fast pattern. --- diff --git a/src/detect-engine-siggroup.c b/src/detect-engine-siggroup.c index 02602d908e..eaf915520c 100644 --- a/src/detect-engine-siggroup.c +++ b/src/detect-engine-siggroup.c @@ -1038,17 +1038,6 @@ int SigGroupHeadAppendSig(DetectEngineCtx *de_ctx, SigGroupHead **sgh, SCLogDebug("(%p)->mpm_content_maxlen %u", *sgh, (*sgh)->mpm_content_maxlen); } } - if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) { - if (s->mpm_uricontent_maxlen > 0) { - if ((*sgh)->mpm_uricontent_maxlen == 0) - (*sgh)->mpm_uricontent_maxlen = s->mpm_uricontent_maxlen; - - if ((*sgh)->mpm_uricontent_maxlen > s->mpm_uricontent_maxlen) - (*sgh)->mpm_uricontent_maxlen = s->mpm_uricontent_maxlen; - - SCLogDebug("(%p)->mpm_uricontent_maxlen %u", *sgh, (*sgh)->mpm_uricontent_maxlen); - } - } return 0; error: @@ -1114,13 +1103,6 @@ int SigGroupHeadCopySigs(DetectEngineCtx *de_ctx, SigGroupHead *src, SigGroupHea SCLogDebug("dst (%p)->mpm_content_maxlen %u", (*dst), (*dst)->mpm_content_maxlen); BUG_ON((*dst)->mpm_content_maxlen == 0); } - if (src->mpm_uricontent_maxlen != 0) { - if ((*dst)->mpm_uricontent_maxlen == 0) - (*dst)->mpm_uricontent_maxlen = src->mpm_uricontent_maxlen; - - if ((*dst)->mpm_uricontent_maxlen > src->mpm_uricontent_maxlen) - (*dst)->mpm_uricontent_maxlen = src->mpm_uricontent_maxlen; - } return 0; error: @@ -1605,6 +1587,45 @@ void SigGroupHeadSetFilemagicFlag(DetectEngineCtx *de_ctx, SigGroupHead *sgh) return; } +/** + * \brief Get size of the shortest mpm pattern. + * + * \param de_ctx detection engine ctx for the signatures + * \param sgh sig group head to set the flag in + * \param list sm_list to consider + */ +uint16_t SigGroupHeadGetMinMpmSize(DetectEngineCtx *de_ctx, + SigGroupHead *sgh, int list) +{ + Signature *s = NULL; + uint32_t sig = 0; + uint16_t min = USHRT_MAX; + + if (sgh == NULL) + return 0; + + for (sig = 0; sig < sgh->sig_cnt; sig++) { + s = sgh->match_array[sig]; + if (s == NULL) + continue; + if (s->sm_lists[list] == NULL) + continue; + + if (s->mpm_sm != NULL && SigMatchListSMBelongsTo(s, s->mpm_sm) == list) + { + DetectContentData *cd = (DetectContentData *)s->mpm_sm->ctx; + if (cd->content_len < min) + min = cd->content_len; + SCLogDebug("cd->content_len %u", cd->content_len); + } + } + + if (min == USHRT_MAX) + min = 0; + SCLogDebug("min mpm size %u", min); + return min; +} + /** * \brief Set the need size flag in the sgh. * diff --git a/src/detect-engine-siggroup.h b/src/detect-engine-siggroup.h index 829b0cefb3..cd6810a1bf 100644 --- a/src/detect-engine-siggroup.h +++ b/src/detect-engine-siggroup.h @@ -88,6 +88,8 @@ void SigGroupHeadSetFilemagicFlag(DetectEngineCtx *, SigGroupHead *); void SigGroupHeadSetFilestoreCount(DetectEngineCtx *, SigGroupHead *); void SigGroupHeadSetFileMd5Flag(DetectEngineCtx *, SigGroupHead *); void SigGroupHeadSetFilesizeFlag(DetectEngineCtx *, SigGroupHead *); +uint16_t SigGroupHeadGetMinMpmSize(DetectEngineCtx *de_ctx, + SigGroupHead *sgh, int list); int SigGroupHeadBuildNonMpmArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh); diff --git a/src/detect-parse.c b/src/detect-parse.c index fedfebe864..7e723e8d13 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -1390,8 +1390,6 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, char *sigstr, if (DetectAppLayerEventPrepare(sig) < 0) goto error; - /* set mpm_content_len */ - /* determine the length of the longest pattern in the sig */ if (sig->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { sig->mpm_content_maxlen = 0; @@ -1409,22 +1407,6 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, char *sigstr, } } } - if (sig->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) { - sig->mpm_uricontent_maxlen = 0; - - for (sm = sig->sm_lists[DETECT_SM_LIST_UMATCH]; sm != NULL; sm = sm->next) { - if (sm->type == DETECT_CONTENT) { - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud == NULL) - continue; - - if (sig->mpm_uricontent_maxlen == 0) - sig->mpm_uricontent_maxlen = ud->content_len; - if (sig->mpm_uricontent_maxlen < ud->content_len) - sig->mpm_uricontent_maxlen = ud->content_len; - } - } - } /* set the packet and app layer flags, but only if the * app layer flag wasn't already set in which case we @@ -3273,11 +3255,6 @@ int SigParseTestMpm01 (void) goto end; } - if (sig->mpm_uricontent_maxlen != 0) { - printf("mpm uricontent max len %"PRIu16", expected 0: ", sig->mpm_uricontent_maxlen); - goto end; - } - result = 1; end: if (sig != NULL) @@ -3314,11 +3291,6 @@ int SigParseTestMpm02 (void) goto end; } - if (sig->mpm_uricontent_maxlen != 0) { - printf("mpm uricontent max len %"PRIu16", expected 0: ", sig->mpm_uricontent_maxlen); - goto end; - } - result = 1; end: if (sig != NULL) diff --git a/src/detect-uricontent.c b/src/detect-uricontent.c index a22479b079..65d2ef9443 100644 --- a/src/detect-uricontent.c +++ b/src/detect-uricontent.c @@ -216,13 +216,13 @@ static inline int DoDetectAppLayerUricontentMatch (DetectEngineThreadCtx *det_ct { int ret = 0; /* run the pattern matcher against the uri */ - if (det_ctx->sgh->mpm_uricontent_maxlen > uri_len) { - SCLogDebug("not searching as pkt payload is smaller than the " - "largest uricontent length we need to match"); + if (det_ctx->sgh->mpm_uricontent_minlen > uri_len) { + SCLogDebug("not searching as uri len is smaller than the " + "shortest uricontent length we need to match"); } else { - SCLogDebug("search: (%p, maxlen %" PRIu32 ", sgh->sig_cnt " - "%" PRIu32 ")", det_ctx->sgh, det_ctx->sgh-> - mpm_uricontent_maxlen, det_ctx->sgh->sig_cnt); + SCLogDebug("search: (%p, minlen %" PRIu32 ", sgh->sig_cnt " + "%" PRIu32 ")", det_ctx->sgh, + det_ctx->sgh->mpm_uricontent_minlen, det_ctx->sgh->sig_cnt); ret += UriPatternSearch(det_ctx, uri, uri_len, flags); diff --git a/src/detect.c b/src/detect.c index 2b7200949e..0f940a98db 100644 --- a/src/detect.c +++ b/src/detect.c @@ -4252,6 +4252,9 @@ int SigAddressPrepareStage4(DetectEngineCtx *de_ctx) SCLogDebug("filestore count %u", sgh->filestore_cnt); SigGroupHeadBuildNonMpmArray(de_ctx, sgh); + + sgh->mpm_uricontent_minlen = SigGroupHeadGetMinMpmSize(de_ctx, sgh, DETECT_SM_LIST_UMATCH); + SCLogDebug("http_uri content min mpm len: %u", sgh->mpm_uricontent_minlen); } if (de_ctx->decoder_event_sgh != NULL) { diff --git a/src/detect.h b/src/detect.h index e35a07761c..17adb8e4dd 100644 --- a/src/detect.h +++ b/src/detect.h @@ -453,7 +453,6 @@ typedef struct Signature_ { /* track max length for content. Indirectly used in grouping: * used to set SigGroupHead::mpm_content_maxlen */ uint16_t mpm_content_maxlen; - uint16_t mpm_uricontent_maxlen; /* SigMatch list used for adding content and friends. E.g. file_data; */ int list; @@ -1030,7 +1029,7 @@ typedef struct SigGroupHead_ { MpmCtx *mpm_hsmd_ctx_tc; MpmCtx *mpm_hscd_ctx_tc; - uint16_t mpm_uricontent_maxlen; + uint16_t mpm_uricontent_minlen; /**< len of shortest mpm pattern in sgh */ /** the number of signatures in this sgh that have the filestore keyword * set. */