From 71ed2d38f5fe6062b3a2ca63343548c069914da5 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Wed, 30 Dec 2009 00:28:19 +0100 Subject: [PATCH] Fix scan patterns sometimes not being added to the scan ctx. Should fix bug #9. --- src/detect-engine-mpm.c | 33 ++++++++++++++++++++++++++++----- src/detect.c | 4 ++-- src/util-mpm-b2g.c | 33 ++++++++++++++++++++++++++++----- src/util-mpm-b3g.c | 6 ++++++ src/util-mpm-wumanber.c | 6 ++++++ 5 files changed, 70 insertions(+), 12 deletions(-) diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index ecacbac6a8..8954e59f0b 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -329,6 +329,7 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead goto error; if (cnt == 1) { + SCLogDebug("sig has just one pattern, so we know we will use it in the scan phase and no searching will be necessary."); ch->nosearch = 1; ch->use = 1; } @@ -368,6 +369,7 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead ContentHash *scan_ch = NULL; SigMatch *sm = s->match; for ( ; sm != NULL; sm = sm->next) { + if (sm->type == DETECT_CONTENT) { DetectContentData *co = (DetectContentData *)sm->ctx; if (co == NULL) @@ -389,18 +391,27 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead continue; } + SCLogDebug("lookup_ch->use %u, cnt %u", lookup_ch->use, lookup_ch->cnt); + if (scan_ch == NULL) { + SCLogDebug("scan_ch == NULL, so selecting lookup_ch->ptr->id %"PRIu32"", lookup_ch->ptr->id); scan_ch = lookup_ch; } else { if (lookup_ch->use == 0) { uint32_t ls = PatternStrength(lookup_ch->ptr->content,lookup_ch->ptr->content_len,sgh->mpm_content_maxlen); uint32_t ss = PatternStrength(scan_ch->ptr->content,scan_ch->ptr->content_len,sgh->mpm_content_maxlen); - if (ls > ss) + if (ls > ss) { + SCLogDebug("lookup_ch->ptr->id %"PRIu32" selected over %"PRIu32"", lookup_ch->ptr->id, scan_ch->ptr->id); scan_ch = lookup_ch; + } else if (ls == ss) { /* if 2 patterns are of equal strength, we pick the longest */ - if (lookup_ch->ptr->content_len > scan_ch->ptr->content_len) + if (lookup_ch->ptr->content_len > scan_ch->ptr->content_len) { + SCLogDebug("lookup_ch->ptr->id %"PRIu32" selected over %"PRIu32" as the first is longer", lookup_ch->ptr->id, scan_ch->ptr->id); scan_ch = lookup_ch; + } + } else { + SCLogDebug("sticking with scan_ch"); } } else { if (scan_ch->use == 0) @@ -408,12 +419,16 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead else { uint32_t ls = PatternStrength(lookup_ch->ptr->content,lookup_ch->ptr->content_len,sgh->mpm_content_maxlen); uint32_t ss = PatternStrength(scan_ch->ptr->content,scan_ch->ptr->content_len,sgh->mpm_content_maxlen); - if (ls > ss) + if (ls > ss) { + SCLogDebug("lookup_ch->ptr->id %"PRIu32" selected over %"PRIu32"", lookup_ch->ptr->id, scan_ch->ptr->id); scan_ch = lookup_ch; + } /* if 2 patterns are of equal strength, we pick the longest */ else if (ls == ss) { - if (lookup_ch->ptr->content_len > scan_ch->ptr->content_len) + if (lookup_ch->ptr->content_len > scan_ch->ptr->content_len) { + SCLogDebug("lookup_ch->ptr->id %"PRIu32" selected over %"PRIu32" as the first is longer", lookup_ch->ptr->id, scan_ch->ptr->id); scan_ch = lookup_ch; + } } } } @@ -435,6 +450,10 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead } else { mpm_table[sgh->mpm_ctx->mpm_type].AddScanPattern(sgh->mpm_ctx, co->content, co->content_len, offset, depth, co->id, s->num, scan_ch->nosearch); } + + SCLogDebug("%"PRIu32" adding co->id %"PRIu32" to the scan phase (s->num %"PRIu32")", s->id, co->id, s->num); + } else { + SCLogDebug("%"PRIu32" no scan pattern selected", s->id); } /* add the rest of the patterns to the search ctx */ for (sm = s->match ; sm != NULL; sm = sm->next) { @@ -444,8 +463,10 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead continue; /* skip the one we already added */ - if (scan_ch != NULL && co == scan_ch->ptr) + if (scan_ch != NULL && co == scan_ch->ptr) { + SCLogDebug("%"PRIu32" co->id %"PRIu32" not added to search, already in scan", s->id, co->id); continue; + } uint16_t offset = s->flags & SIG_FLAG_RECURSIVE ? 0 : co->offset; uint16_t depth = s->flags & SIG_FLAG_RECURSIVE ? 0 : co->depth; @@ -455,6 +476,8 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead } else { mpm_table[sgh->mpm_ctx->mpm_type].AddPattern(sgh->mpm_ctx, co->content, co->content_len, offset, depth, co->id, s->num); } + + SCLogDebug("%"PRIu32" adding co->id %"PRIu32" to the search phase", s->id, co->id); } } } diff --git a/src/detect.c b/src/detect.c index b69d592f94..a1b0a1855d 100644 --- a/src/detect.c +++ b/src/detect.c @@ -8029,8 +8029,8 @@ static int SigTestContent06Real (int mpm_type) { result = 0; goto end; } - de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Test 32 sig2\"; content:\"01234567890123456789012345678901\"; content:\"abcdefg\"; sid:2;)"); - if (de_ctx->sig_list == NULL) { + de_ctx->sig_list->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Test 32 sig2\"; content:\"01234567890123456789012345678901\"; content:\"abcdefg\"; sid:2;)"); + if (de_ctx->sig_list->next == NULL) { result = 0; goto end; } diff --git a/src/util-mpm-b2g.c b/src/util-mpm-b2g.c index 9f01a4da6a..706981a649 100644 --- a/src/util-mpm-b2g.c +++ b/src/util-mpm-b2g.c @@ -84,12 +84,16 @@ static inline void B2gEndMatchAppend(MpmCtx *mpm_ctx, B2gPattern *p, uint16_t offset, uint16_t depth, uint32_t pid, uint32_t sid, uint8_t nosearch) { + SCLogDebug("pid %"PRIu32", sid %"PRIu32"", pid, sid); + MpmEndMatch *em = MpmAllocEndMatch(mpm_ctx); if (em == NULL) { printf("ERROR: B2gAllocEndMatch failed\n"); return; } + SCLogDebug("em alloced at %p", em); + em->id = pid; em->sig_id = sid; em->depth = depth; @@ -100,6 +104,7 @@ static inline void B2gEndMatchAppend(MpmCtx *mpm_ctx, B2gPattern *p, if (p->em == NULL) { p->em = em; + SCLogDebug("m %p m->sig_id %"PRIu32"", em, em->sig_id); return; } @@ -108,6 +113,13 @@ static inline void B2gEndMatchAppend(MpmCtx *mpm_ctx, B2gPattern *p, m = m->next; } m->next = em; + + m = p->em; + SCLogDebug("m %p m->sig_id %"PRIu32"", m, m->sig_id); + while (m->next) { + m = m->next; + SCLogDebug("m %p m->sig_id %"PRIu32"", m, m->sig_id); + } } #ifdef PRINTMATCH @@ -371,6 +383,17 @@ static inline int B2gAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, if (mpm_ctx->pattern_cnt == 1) mpm_ctx->search_minlen = patlen; else if (mpm_ctx->search_minlen > patlen) mpm_ctx->search_minlen = patlen; } + } else { + /* if we're reusing a pattern, check we need to check that it is a + * scan pattern if that is what we're adding. If so we set the pattern + * to be a scan pattern. */ + + //printf("reusing B2gAddPattern: ci \""); prt(p->ci,p->len); + //printf("\" cs \""); prt(p->cs,p->len); + //printf("\"\n"); + + if (scan) + p->flags |= B2G_SCAN; } /* we need a match */ @@ -1173,7 +1196,7 @@ uint32_t B2gScanBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatc MpmEndMatch *em; for (em = p->em; em; em = em->next) { - //printf("em %p id %" PRIu32 "\n", em, em->id); + SCLogDebug("em %p id %" PRIu32 "", em, em->id); if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id], j, p->len)) matches++; } @@ -1192,7 +1215,7 @@ uint32_t B2gScanBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatc MpmEndMatch *em; for (em = p->em; em; em = em->next) { - //printf("em %p id %" PRIu32 "\n", em, em->id); + SCLogDebug("em %p pid %" PRIu32 ", sid %"PRIu32"", em, em->id, em->sig_id); if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id], j, p->len)) matches++; } @@ -1202,7 +1225,7 @@ uint32_t B2gScanBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatc } } skip_loop: - //SCLogDebug("skipped"); + SCLogDebug("skipped"); //SCLogDebug("output at pos %" PRIu32 ": ", j); prt(buf + (j), ctx->scan_m); printf("\n"); ; } @@ -1220,10 +1243,10 @@ skip_loop: COUNT(tctx->scan_stat_total_shift += (ctx->scan_m - B2G_Q + 1)); pos = pos + ctx->scan_m - B2G_Q + 1; - //SCLogDebug("pos %"PRIu32"", pos); + SCLogDebug("pos %"PRIu32"", pos); } - //SCLogDebug("matches %"PRIu32"", matches); + SCLogDebug("matches %"PRIu32"", matches); return matches; } diff --git a/src/util-mpm-b3g.c b/src/util-mpm-b3g.c index 86d40da461..8a6e709788 100644 --- a/src/util-mpm-b3g.c +++ b/src/util-mpm-b3g.c @@ -367,6 +367,12 @@ static inline int B3gAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, if (mpm_ctx->pattern_cnt == 1) mpm_ctx->search_minlen = patlen; else if (mpm_ctx->search_minlen > patlen) mpm_ctx->search_minlen = patlen; } + } else { + /* if we're reusing a pattern, check we need to check that it is a + * scan pattern if that is what we're adding. If so we set the pattern + * to be a scan pattern. */ + if (scan) + p->flags |= B3G_SCAN; } /* we need a match */ diff --git a/src/util-mpm-wumanber.c b/src/util-mpm-wumanber.c index 7e67646547..86a94566fe 100644 --- a/src/util-mpm-wumanber.c +++ b/src/util-mpm-wumanber.c @@ -436,6 +436,12 @@ static inline int WmAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, u if (mpm_ctx->pattern_cnt == 1) mpm_ctx->search_minlen = patlen; else if (mpm_ctx->search_minlen > patlen) mpm_ctx->search_minlen = patlen; } + } else { + /* if we're reusing a pattern, check we need to check that it is a + * scan pattern if that is what we're adding. If so we set the pattern + * to be a scan pattern. */ + if (scan) + p->flags = WUMANBER_SCAN; } /* we need a match */