From 9ff5703c4972effbb9a93dcbaefb18917c0a566b Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Thu, 7 Jul 2016 19:25:10 +0200 Subject: [PATCH] packet/stream: mpm prefilter engine --- src/detect-engine-mpm.c | 15 ++ src/detect-engine-mpm.h | 3 - src/detect-engine-payload.c | 114 ++++----- src/detect-engine-payload.h | 3 + src/detect-fast-pattern.c | 491 ------------------------------------ src/detect.c | 55 +--- src/detect.h | 4 + 7 files changed, 80 insertions(+), 605 deletions(-) diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 0d625b1119..165d48c668 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -48,6 +48,7 @@ #include "detect-content.h" +#include "detect-engine-payload.h" #include "detect-engine-uri.h" #include "detect-engine-hmd.h" @@ -1230,6 +1231,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) sh->mpm_packet_ctx = mpm_store->mpm_ctx; if (sh->mpm_packet_ctx) sh->flags |= SIG_GROUP_HEAD_MPM_PACKET; + + PrefilterPktPayloadRegister(sh, mpm_store->mpm_ctx); } mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_TCP_STREAM_TS); @@ -1239,6 +1242,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) sh->mpm_stream_ctx = mpm_store->mpm_ctx; if (sh->mpm_stream_ctx) sh->flags |= SIG_GROUP_HEAD_MPM_STREAM; + + PrefilterPktStreamRegister(sh, mpm_store->mpm_ctx); } } if (SGH_DIRECTION_TC(sh)) { @@ -1248,6 +1253,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) sh->mpm_packet_ctx = mpm_store->mpm_ctx; if (sh->mpm_packet_ctx) sh->flags |= SIG_GROUP_HEAD_MPM_PACKET; + + PrefilterPktPayloadRegister(sh, mpm_store->mpm_ctx); } mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_TCP_STREAM_TC); @@ -1256,6 +1263,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) sh->mpm_stream_ctx = mpm_store->mpm_ctx; if (sh->mpm_stream_ctx) sh->flags |= SIG_GROUP_HEAD_MPM_STREAM; + + PrefilterPktStreamRegister(sh, mpm_store->mpm_ctx); } } } else if (SGH_PROTO(sh, IPPROTO_UDP)) { @@ -1268,6 +1277,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) if (sh->mpm_packet_ctx != NULL) sh->flags |= SIG_GROUP_HEAD_MPM_PACKET; + + PrefilterPktPayloadRegister(sh, mpm_store->mpm_ctx); } } if (SGH_DIRECTION_TC(sh)) { @@ -1278,6 +1289,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) if (sh->mpm_packet_ctx != NULL) sh->flags |= SIG_GROUP_HEAD_MPM_PACKET; + + PrefilterPktPayloadRegister(sh, mpm_store->mpm_ctx); } } } else { @@ -1288,6 +1301,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) if (sh->mpm_packet_ctx != NULL) sh->flags |= SIG_GROUP_HEAD_MPM_PACKET; + + PrefilterPktPayloadRegister(sh, mpm_store->mpm_ctx); } } diff --git a/src/detect-engine-mpm.h b/src/detect-engine-mpm.h index 5e83a25539..bb73a6a303 100644 --- a/src/detect-engine-mpm.h +++ b/src/detect-engine-mpm.h @@ -40,9 +40,6 @@ void DetectMpmPrepareBuiltinMpms(DetectEngineCtx *de_ctx); uint32_t PatternStrength(uint8_t *, uint16_t); uint16_t PatternMatchDefaultMatcher(void); -uint32_t PacketPatternSearchWithStreamCtx(DetectEngineThreadCtx *, Packet *); -uint32_t PacketPatternSearch(DetectEngineThreadCtx *, Packet *); -uint32_t StreamPatternSearch(DetectEngineThreadCtx *, Packet *, StreamMsg *, uint8_t); uint32_t DnsQueryPatternSearch(DetectEngineThreadCtx *det_ctx, uint8_t *buffer, uint32_t buffer_len, uint8_t flags); void PacketPatternCleanup(ThreadVars *, DetectEngineThreadCtx *); diff --git a/src/detect-engine-payload.c b/src/detect-engine-payload.c index d3a17bac35..85f69925b0 100644 --- a/src/detect-engine-payload.c +++ b/src/detect-engine-payload.c @@ -32,6 +32,7 @@ #include "detect-engine.h" #include "detect-parse.h" #include "detect-engine-content-inspection.h" +#include "detect-engine-prefilter.h" #include "stream.h" @@ -44,100 +45,77 @@ #include "util-mpm-ac.h" -uint32_t PacketPatternSearchWithStreamCtx(DetectEngineThreadCtx *det_ctx, - const Packet *p) +static void PrefilterPktStream(DetectEngineThreadCtx *det_ctx, + Packet *p, const void *pectx) { SCEnter(); - uint32_t ret = 0; + const MpmCtx *mpm_ctx = (MpmCtx *)pectx; + const StreamMsg *smsg = det_ctx->smsg; - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_stream_ctx == NULL); - if (det_ctx->sgh->mpm_stream_ctx == NULL) - SCReturnInt(0); + /* for established packets inspect any smsg we may have queued up */ + if (p->flowflags & FLOW_PKT_ESTABLISHED) { + SCLogDebug("p->flowflags & FLOW_PKT_ESTABLISHED"); - if (p->payload_len >= det_ctx->sgh->mpm_stream_ctx->minlen) { - ret = mpm_table[det_ctx->sgh->mpm_stream_ctx->mpm_type]. - Search(det_ctx->sgh->mpm_stream_ctx, &det_ctx->mtc, &det_ctx->pmq, - p->payload, p->payload_len); + for ( ; smsg != NULL; smsg = smsg->next) { + if (smsg->data_len >= mpm_ctx->minlen) { + (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, + &det_ctx->mtcs, &det_ctx->pmq, + smsg->data, smsg->data_len); + } + } + } else { + SCLogDebug("NOT p->flowflags & FLOW_PKT_ESTABLISHED"); } - SCReturnInt(ret); -} - -/** \brief Pattern match -- searches for only one pattern per signature. - * - * \param det_ctx detection engine thread ctx - * \param p packet - * \param smsg stream msg (reassembled stream data) - * \param flags stream flags - * - * \retval ret number of matches - */ -uint32_t StreamPatternSearch(DetectEngineThreadCtx *det_ctx, const Packet *p, - const StreamMsg *smsg, const uint8_t flags) -{ - SCEnter(); - - uint32_t ret = 0; - - //PrintRawDataFp(stdout, smsg->data.data, smsg->data.data_len); - - uint32_t r; - for ( ; smsg != NULL; smsg = smsg->next) { - if (smsg->data_len >= det_ctx->sgh->mpm_stream_ctx->minlen) { - r = mpm_table[det_ctx->sgh->mpm_stream_ctx->mpm_type]. - Search(det_ctx->sgh->mpm_stream_ctx, &det_ctx->mtcs, - &det_ctx->pmq, smsg->data, smsg->data_len); - if (r > 0) { - ret += r; - } + /* packets that have not been added to the stream will be inspected + * as if they are stream chunks */ + if ((!(p->flags & PKT_NOPAYLOAD_INSPECTION)) && + !(p->flags & PKT_STREAM_ADD)) + { + if (p->payload_len >= mpm_ctx->minlen) { + (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, + &det_ctx->mtc, &det_ctx->pmq, + p->payload, p->payload_len); } } +} - SCReturnInt(ret); +int PrefilterPktStreamRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx) +{ + return PrefilterAppendEngine(sgh, PrefilterPktStream, mpm_ctx, NULL); } -/** \brief Pattern match -- searches for only one pattern per signature. - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * - * \retval ret number of matches - */ -uint32_t PacketPatternSearch(DetectEngineThreadCtx *det_ctx, Packet *p) +static void PrefilterPktPayload(DetectEngineThreadCtx *det_ctx, + Packet *p, const void *pectx) { SCEnter(); - uint32_t ret = 0; - const MpmCtx *mpm_ctx = NULL; - - mpm_ctx = det_ctx->sgh->mpm_packet_ctx; - if (unlikely(mpm_ctx == NULL)) - SCReturnInt(0); + const MpmCtx *mpm_ctx = (MpmCtx *)pectx; if (p->payload_len < mpm_ctx->minlen) - SCReturnInt(0); + SCReturn; #ifdef __SC_CUDA_SUPPORT__ if (p->cuda_pkt_vars.cuda_mpm_enabled && p->pkt_src == PKT_SRC_WIRE) { - ret = SCACCudaPacketResultsProcessing(p, mpm_ctx, &det_ctx->pmq); + (void)SCACCudaPacketResultsProcessing(p, mpm_ctx, &det_ctx->pmq); } else { - ret = mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, - &det_ctx->mtc, - &det_ctx->pmq, - p->payload, - p->payload_len); + (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, + &det_ctx->mtc, &det_ctx->pmq, + p->payload, p->payload_len); } #else - ret = mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, - &det_ctx->mtc, - &det_ctx->pmq, - p->payload, - p->payload_len); + (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, + &det_ctx->mtc, &det_ctx->pmq, + p->payload, p->payload_len); #endif +} - SCReturnInt(ret); +int PrefilterPktPayloadRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx) +{ + return PrefilterAppendEngine(sgh, PrefilterPktPayload, mpm_ctx, NULL); } + /** * \brief Do the content inspection & validation for a signature * diff --git a/src/detect-engine-payload.h b/src/detect-engine-payload.h index d6220b18a5..67d0be2465 100644 --- a/src/detect-engine-payload.h +++ b/src/detect-engine-payload.h @@ -24,6 +24,9 @@ #ifndef __DETECT_ENGINE_PAYLOAD_H__ #define __DETECT_ENGINE_PAYLOAD_H__ +int PrefilterPktPayloadRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx); +int PrefilterPktStreamRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx); + int DetectEngineInspectPacketPayload(DetectEngineCtx *, DetectEngineThreadCtx *, Signature *, Flow *, Packet *); int DetectEngineInspectStreamPayload(DetectEngineCtx *, diff --git a/src/detect-fast-pattern.c b/src/detect-fast-pattern.c index b2e5694167..1180209bc8 100644 --- a/src/detect-fast-pattern.c +++ b/src/detect-fast-pattern.c @@ -518,488 +518,6 @@ int DetectFastPatternTest04(void) return result; } -/** - * \test Checks that a fast_pattern is used in the mpm phase. - */ -int DetectFastPatternTest05(void) -{ - uint8_t *buf = (uint8_t *) "Oh strin1. But what " - "strin2. This is strings3. We strins_str4. we " - "have strins_string5"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; fast_pattern; " - "content:\"strings_str4\"; content:\"strings_string5\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearchWithStreamCtx(det_ctx, p) != 0) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - -end: - UTHFreePackets(&p, 1); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that a fast_pattern is used in the mpm phase. - */ -int DetectFastPatternTest06(void) -{ - uint8_t *buf = (uint8_t *) "Oh this is a string1. But what is this with " - "string2. This is strings3. We have strings_str4. We also have " - "strings_string5"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; fast_pattern; " - "content:\"strings_str4\"; content:\"strings_string5\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearchWithStreamCtx(det_ctx, p) != 0) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - -end: - UTHFreePackets(&p, 1); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that a fast_pattern is used in the mpm phase, when the payload - * doesn't contain the fast_pattern string within it. - */ -int DetectFastPatternTest07(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. now here comes our " - "dark knight strings_string5. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; fast_pattern; " - "content:\"strings_str4\"; content:\"strings_string5\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearchWithStreamCtx(det_ctx, p) == 0) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - -end: - UTHFreePackets(&p, 1); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that a fast_pattern is used in the mpm phase and that we get - * exactly 1 match for the mpm phase. - */ -int DetectFastPatternTest08(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. now here comes our " - "dark knight strings3. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - printf("de_ctx init: "); - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; fast_pattern; " - "content:\"strings_str4\"; content:\"strings_string5\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = PacketPatternSearchWithStreamCtx(det_ctx, p); - if (r != 1) { - printf("expected 1, got %"PRIu32": ", r); - goto end; - } - - result = 1; -end: - UTHFreePackets(&p, 1); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} -/** - * \test Checks that a fast_pattern is used in the mpm phase, when the payload - * doesn't contain the fast_pattern string within it. - */ -int DetectFastPatternTest09(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. no_strings4 _imp now here " - "comes our dark knight strings3. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; " - "content:\"strings4_imp\"; fast_pattern; " - "content:\"strings_string5\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearchWithStreamCtx(det_ctx, p) == 0) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - -end: - UTHFreePackets(&p, 1); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that a the SigInit chooses the fast_pattern with better pattern - * strength, when we have multiple fast_patterns in the Signature. Also - * checks that we get a match for the fast_pattern from the mpm phase. - */ -int DetectFastPatternTest10(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. strings4_imp now here " - "comes our dark knight strings5. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - printf("de_ctx init: "); - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; " - "content:\"strings4_imp\"; fast_pattern; " - "content:\"strings_string5\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = PacketPatternSearchWithStreamCtx(det_ctx, p); - if (r != 1) { - printf("expected 1, got %"PRIu32": ", r); - goto end; - } - - result = 1; -end: - UTHFreePackets(&p, 1); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that a the SigInit chooses the fast_pattern with better pattern - * strength, when we have multiple fast_patterns in the Signature. Also - * checks that we get no matches for the fast_pattern from the mpm phase. - */ -int DetectFastPatternTest11(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. strings5_imp now here " - "comes our dark knight strings5. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; " - "content:\"strings4_imp\"; fast_pattern; " - "content:\"strings_string5\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearchWithStreamCtx(det_ctx, p) == 0) - result = 1; - - -end: - UTHFreePackets(&p, 1); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - return result; -} - -/** - * \test Checks that we don't get a match for the mpm phase. - */ -int DetectFastPatternTest12(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. strings5_imp now here " - "comes our dark knight strings5. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; " - "content:\"strings4_imp\"; " - "content:\"strings_string5\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearchWithStreamCtx(det_ctx, p) == 0) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - -end: - UTHFreePackets(&p, 1); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that a the SigInit chooses the fast_pattern with a better - * strength from the available patterns, when we don't specify a - * fast_pattern. We also check that we get a match from the mpm - * phase. - */ -int DetectFastPatternTest13(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. strings5_imp now here " - "comes our dark knight strings_string5. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - printf("de_ctx init: "); - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; " - "content:\"strings4_imp\"; " - "content:\"strings_string5\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = PacketPatternSearchWithStreamCtx(det_ctx, p); - if (r != 1) { - printf("expected 1 result, got %"PRIu32": ", r); - goto end; - } - - result = 1; -end: - UTHFreePackets(&p, 1); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - /** * \test Checks to make sure that other sigs work that should when fast_pattern is inspecting on the same payload * @@ -19430,15 +18948,6 @@ void DetectFastPatternRegisterTests(void) UtRegisterTest("DetectFastPatternTest02", DetectFastPatternTest02); UtRegisterTest("DetectFastPatternTest03", DetectFastPatternTest03); UtRegisterTest("DetectFastPatternTest04", DetectFastPatternTest04); - UtRegisterTest("DetectFastPatternTest05", DetectFastPatternTest05); - UtRegisterTest("DetectFastPatternTest06", DetectFastPatternTest06); - UtRegisterTest("DetectFastPatternTest07", DetectFastPatternTest07); - UtRegisterTest("DetectFastPatternTest08", DetectFastPatternTest08); - UtRegisterTest("DetectFastPatternTest09", DetectFastPatternTest09); - UtRegisterTest("DetectFastPatternTest10", DetectFastPatternTest10); - UtRegisterTest("DetectFastPatternTest11", DetectFastPatternTest11); - UtRegisterTest("DetectFastPatternTest12", DetectFastPatternTest12); - UtRegisterTest("DetectFastPatternTest13", DetectFastPatternTest13); UtRegisterTest("DetectFastPatternTest14", DetectFastPatternTest14); UtRegisterTest("DetectFastPatternTest15", DetectFastPatternTest15); UtRegisterTest("DetectFastPatternTest16", DetectFastPatternTest16); diff --git a/src/detect.c b/src/detect.c index e9fc09f063..6b5b70b649 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1072,42 +1072,9 @@ static inline void DetectMpmPrefilter(DetectEngineCtx *de_ctx, } } } - - if (smsg != NULL && (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_STREAM)) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_STREAM); - StreamPatternSearch(det_ctx, p, smsg, flags); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_STREAM); - } else { - SCLogDebug("smsg NULL or no stream mpm for this sgh"); - } } else { SCLogDebug("NOT p->flowflags & FLOW_PKT_ESTABLISHED"); } - - if (p->payload_len > 0 && (!(p->flags & PKT_NOPAYLOAD_INSPECTION))) { - if (!(p->flags & PKT_STREAM_ADD) && (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_STREAM)) { - *sms_runflags |= SMS_USED_PM; - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_PKT_STREAM); - PacketPatternSearchWithStreamCtx(det_ctx, p); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_PKT_STREAM); - } - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_PACKET) { - /* run the multi packet matcher against the payload of the packet */ - SCLogDebug("search: (%p, sgh->sig_cnt %" PRIu32 ")", - det_ctx->sgh, det_ctx->sgh->sig_cnt); - - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_PACKET); - PacketPatternSearch(det_ctx, p); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_PACKET); - - *sms_runflags |= SMS_USED_PM; - } else { - SCLogDebug("not packet"); - } - } else { - SCLogDebug("how did we get here?"); - } - /* UDP DNS inspection is independent of est or not */ if (alproto == ALPROTO_DNS && has_state) { if (p->flowflags & FLOW_PKT_TOSERVER) { @@ -1266,7 +1233,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh int smatch = 0; /* signature match: 1, no match: 0 */ #endif uint8_t flow_flags = 0; /* flow/state flags */ - StreamMsg *smsg = NULL; Signature *s = NULL; Signature *next_s = NULL; uint8_t alversion = 0; @@ -1281,7 +1247,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh p->alerts.cnt = 0; det_ctx->filestore_cnt = 0; - + det_ctx->smsg = NULL; det_ctx->base64_decoded_len = 0; /* No need to perform any detection on this packet, if the the given flag is set.*/ @@ -1358,7 +1324,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh } PACKET_PROFILING_DETECT_END(p, PROF_DETECT_GETSGH); - smsg = SigMatchSignaturesGetSmsg(pflow, p, flow_flags); + det_ctx->smsg = SigMatchSignaturesGetSmsg(pflow, p, flow_flags); #if 0 StreamMsg *tmpsmsg = smsg; while (tmpsmsg) { @@ -1428,7 +1394,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh #ifdef DEBUG if (pflow) { - DebugInspectIds(p, pflow, smsg); + DebugInspectIds(p, pflow, det_ctx->smsg); } #endif } else { /* p->flags & PKT_HAS_FLOW */ @@ -1472,7 +1438,8 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh /* create our prefilter mask */ SignatureMask mask = 0; - PacketCreateMask(p, &mask, alproto, has_state, smsg, app_decoder_events); + PacketCreateMask(p, &mask, alproto, has_state, det_ctx->smsg, + app_decoder_events); /* build and prefilter non_pf list against the mask of the packet */ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_NONMPMLIST); @@ -1487,7 +1454,8 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh /* run the mpm for each type */ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM); - DetectMpmPrefilter(de_ctx, det_ctx, smsg, p, flow_flags, alproto, has_state, &sms_runflags); + DetectMpmPrefilter(de_ctx, det_ctx, det_ctx->smsg, p, flow_flags, + alproto, has_state, &sms_runflags); PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM); #ifdef PROFILING @@ -1663,12 +1631,12 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh * but not for a "dsize" signature */ if (sflags & SIG_FLAG_REQUIRE_STREAM) { char pmatch = 0; - if (smsg != NULL) { + if (det_ctx->smsg != NULL) { uint8_t pmq_idx = 0; - StreamMsg *smsg_inspect = smsg; + StreamMsg *smsg_inspect = det_ctx->smsg; for ( ; smsg_inspect != NULL; smsg_inspect = smsg_inspect->next, pmq_idx++) { if (DetectEngineInspectStreamPayload(de_ctx, det_ctx, s, pflow, smsg_inspect->data, smsg_inspect->data_len) == 1) { - SCLogDebug("match in smsg %p", smsg); + SCLogDebug("match in smsg %p", smsg_inspect); pmatch = 1; det_ctx->flags |= DETECT_ENGINE_THREAD_CTX_STREAM_CONTENT_MATCH; /* Tell the engine that this reassembled stream can drop the @@ -1937,7 +1905,8 @@ end: /* if we had no alerts that involved the smsgs, * we can get rid of them now. */ - StreamMsgReturnListToPool(smsg); + StreamMsgReturnListToPool(det_ctx->smsg); + det_ctx->smsg = NULL; } PACKET_PROFILING_DETECT_END(p, PROF_DETECT_CLEANUP); diff --git a/src/detect.h b/src/detect.h index 5f9ecc86e9..6c8b333ba6 100644 --- a/src/detect.h +++ b/src/detect.h @@ -45,6 +45,8 @@ #include "detect-mark.h" +#include "stream.h" + #define DETECT_MAX_RULE_SIZE 8192 /* forward declarations for the structures from detect-engine-sigorder.h */ @@ -834,6 +836,8 @@ typedef struct DetectEngineThreadCtx_ { MpmThreadCtx mtcs; /**< thread ctx for stream mpm */ PrefilterRuleStore pmq; + StreamMsg *smsg; + /** SPM thread context used for scanning. This has been cloned from the * prototype held by DetectEngineCtx. */ SpmThreadCtx *spm_thread_ctx;