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.
pull/1652/head
Victor Julien 10 years ago
parent df95d375bb
commit e529ebb50e

@ -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.
*

@ -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);

@ -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)

@ -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);

@ -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) {

@ -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. */

Loading…
Cancel
Save