diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index c491d7fbaf..8ec8933f35 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -191,14 +191,12 @@ uint16_t PatternMatchDefaultMatcher(void) { /** \brief Pattern match -- searches for only one pattern per signature. * - * \param tv threadvars * \param det_ctx detection engine thread ctx * \param p packet to inspect * * \retval ret number of matches */ -uint32_t PacketPatternSearch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, - Packet *p) +uint32_t PacketPatternSearch(DetectEngineThreadCtx *det_ctx, Packet *p) { SCEnter(); @@ -340,7 +338,6 @@ uint32_t HttpRawHeaderPatternSearch(DetectEngineThreadCtx *det_ctx, /** \brief Pattern match -- searches for only one pattern per signature. * - * \param tv threadvars * \param det_ctx detection engine thread ctx * \param p packet * \param smsg stream msg (reassembled stream data) @@ -348,8 +345,8 @@ uint32_t HttpRawHeaderPatternSearch(DetectEngineThreadCtx *det_ctx, * * \retval ret number of matches */ -uint32_t StreamPatternSearch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, - Packet *p, StreamMsg *smsg, uint8_t flags) +uint32_t StreamPatternSearch(DetectEngineThreadCtx *det_ctx, Packet *p, + StreamMsg *smsg, uint8_t flags) { SCEnter(); @@ -751,6 +748,12 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx, } } } + if (SignatureHasPacketContent(s)) { + sgh->flags |= SIG_GROUP_HEAD_MPM_PACKET; + } + if (SignatureHasStreamContent(s)) { + sgh->flags |= SIG_GROUP_HEAD_MPM_STREAM; + } break; } /* case DETECT_CONTENT */ @@ -804,6 +807,8 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx, if (ud->flags & DETECT_CONTENT_NEGATED) s->flags |= SIG_FLAG_MPM_URICONTENT_NEG; + sgh->flags |= SIG_GROUP_HEAD_MPM_URI; + break; } /* case DETECT_URICONTENT */ @@ -857,6 +862,8 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx, if (hcbd->flags & DETECT_CONTENT_NEGATED) s->mpm_flags |= SIG_FLAG_MPM_HCBDCONTENT_NEG; + sgh->flags |= SIG_GROUP_HEAD_MPM_HCBD; + break; } /* case DETECT_AL_HTTP_CLIENT_BODY */ @@ -910,6 +917,8 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx, if (hhd->flags & DETECT_CONTENT_NEGATED) s->mpm_flags |= SIG_FLAG_MPM_HHDCONTENT_NEG; + sgh->flags |= SIG_GROUP_HEAD_MPM_HHD; + break; } /* case DETECT_AL_HTTP_HEADER */ @@ -963,6 +972,8 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx, if (hrhd->flags & DETECT_CONTENT_NEGATED) s->mpm_flags |= SIG_FLAG_MPM_HRHDCONTENT_NEG; + sgh->flags |= SIG_GROUP_HEAD_MPM_HRHD; + break; } /* case DETECT_AL_HTTP_RAW_HEADER */ diff --git a/src/detect-engine-mpm.h b/src/detect-engine-mpm.h index 0e5f572485..f272654e9d 100644 --- a/src/detect-engine-mpm.h +++ b/src/detect-engine-mpm.h @@ -33,9 +33,9 @@ uint16_t PatternMatchDefaultMatcher(void); -uint32_t PacketPatternSearch(ThreadVars *, DetectEngineThreadCtx *, Packet *); +uint32_t PacketPatternSearch(DetectEngineThreadCtx *, Packet *); uint32_t UriPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint16_t); -uint32_t StreamPatternSearch(ThreadVars *, DetectEngineThreadCtx *, Packet *, StreamMsg *, uint8_t); +uint32_t StreamPatternSearch(DetectEngineThreadCtx *, Packet *, StreamMsg *, uint8_t); uint32_t HttpClientBodyPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t); uint32_t HttpHeaderPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t); uint32_t HttpRawHeaderPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t); diff --git a/src/detect-engine-uri.c b/src/detect-engine-uri.c index c90c4edcce..eaed36f739 100644 --- a/src/detect-engine-uri.c +++ b/src/detect-engine-uri.c @@ -195,15 +195,15 @@ static int DoInspectPacketUri(DetectEngineCtx *de_ctx, //PrintawDataFp(stdout,ud->content,ud->content_len); /* If we got no matches from the mpm, avoid searching (just check if negated) */ - if (det_ctx->de_have_httpuri == TRUE) { + //if (det_ctx->de_have_httpuri == TRUE) { /* do the actual search with boyer moore precooked ctx */ if (ud->flags & DETECT_CONTENT_NOCASE) found = BoyerMooreNocase(ud->content, ud->content_len, spayload, spayload_len, ud->bm_ctx->bmGs, ud->bm_ctx->bmBc); else found = BoyerMoore(ud->content, ud->content_len, spayload, spayload_len, ud->bm_ctx->bmGs, ud->bm_ctx->bmBc); - } else { - found = NULL; - } + //} else { + // found = NULL; + //} /* next we evaluate the result in combination with the * negation flag. */ @@ -377,47 +377,47 @@ int DetectEngineInspectPacketUris(DetectEngineCtx *de_ctx, goto end; } - det_ctx->de_have_httpuri = TRUE; - /* If we have the uricontent multi pattern matcher signatures in - signature list, then search the received HTTP uri(s) in the htp - state against those patterns */ - if (s->flags & SIG_FLAG_MPM_URICONTENT) { - if (det_ctx->de_mpm_scanned_uri == FALSE) { - uint32_t cnt = DetectUricontentInspectMpm(det_ctx, f, htp_state); - - /* only consider uri sigs if we've seen at least one match */ - /** \warning when we start supporting negated uri content matches - * we need to update this check as well */ - if (cnt <= 0) { - det_ctx->de_have_httpuri = FALSE; - } - - SCLogDebug("uricontent cnt %"PRIu32"", cnt); - - /* make sure we don't inspect this mpm again */ - det_ctx->de_mpm_scanned_uri = TRUE; - - } - } + //det_ctx->de_have_httpuri = TRUE; + ///* If we have the uricontent multi pattern matcher signatures in + // signature list, then search the received HTTP uri(s) in the htp + // state against those patterns */ + //if (s->flags & SIG_FLAG_MPM_URICONTENT) { + // if (det_ctx->de_mpm_scanned_uri == FALSE) { + // uint32_t cnt = DetectUricontentInspectMpm(det_ctx, f, htp_state); + // + // /* only consider uri sigs if we've seen at least one match */ + // /** \warning when we start supporting negated uri content matches + // * we need to update this check as well */ + // if (cnt <= 0) { + // det_ctx->de_have_httpuri = FALSE; + // } + // + // SCLogDebug("uricontent cnt %"PRIu32"", cnt); + // + // /* make sure we don't inspect this mpm again */ + // det_ctx->de_mpm_scanned_uri = TRUE; + // + // } + //} /* if we don't have a uri, don't bother inspecting */ - if (det_ctx->de_have_httpuri == FALSE && !(s->flags & SIG_FLAG_MPM_URICONTENT_NEG)) { - SCLogDebug("We don't have uri"); - goto end; - } - - if ((s->flags & SIG_FLAG_MPM_URICONTENT) && (det_ctx->de_mpm_scanned_uri == TRUE)) { - if (det_ctx->pmq.pattern_id_bitarray != NULL) { - /* filter out sigs that want pattern matches, but - * have no matches */ - if (!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_uripattern_id / 8)] & (1<<(s->mpm_uripattern_id % 8))) && - (s->flags & SIG_FLAG_MPM_URICONTENT) && !(s->flags & SIG_FLAG_MPM_URICONTENT_NEG)) { - SCLogDebug("mpm sig without matches (pat id %"PRIu32 - " check in uri).", s->mpm_uripattern_id); - goto end; - } - } - } + //if (det_ctx->de_have_httpuri == FALSE && !(s->flags & SIG_FLAG_MPM_URICONTENT_NEG)) { + // SCLogDebug("We don't have uri"); + // goto end; + //} + // + //if ((s->flags & SIG_FLAG_MPM_URICONTENT) && (det_ctx->de_mpm_scanned_uri == TRUE)) { + // if (det_ctx->pmq.pattern_id_bitarray != NULL) { + // /* filter out sigs that want pattern matches, but + // * have no matches */ + // if (!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_uripattern_id / 8)] & (1<<(s->mpm_uripattern_id % 8))) && + // (s->flags & SIG_FLAG_MPM_URICONTENT) && !(s->flags & SIG_FLAG_MPM_URICONTENT_NEG)) { + // SCLogDebug("mpm sig without matches (pat id %"PRIu32 + // " check in uri).", s->mpm_uripattern_id); + // goto end; + // } + // } + //} sm = s->sm_lists[DETECT_SM_LIST_UMATCH]; diff --git a/src/detect-fast-pattern.c b/src/detect-fast-pattern.c index 789588cb61..8ea8354730 100644 --- a/src/detect-fast-pattern.c +++ b/src/detect-fast-pattern.c @@ -527,7 +527,7 @@ int DetectFastPatternTest05(void) /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearch(&th_v, det_ctx, p) != 0) + if (PacketPatternSearch(det_ctx, p) != 0) result = 1; SigGroupCleanup(de_ctx); @@ -577,7 +577,7 @@ int DetectFastPatternTest06(void) /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearch(&th_v, det_ctx, p) != 0) + if (PacketPatternSearch(det_ctx, p) != 0) result = 1; SigGroupCleanup(de_ctx); @@ -628,7 +628,7 @@ int DetectFastPatternTest07(void) /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearch(&th_v, det_ctx, p) == 0) + if (PacketPatternSearch(det_ctx, p) == 0) result = 1; SigGroupCleanup(de_ctx); @@ -683,7 +683,7 @@ int DetectFastPatternTest08(void) /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = PacketPatternSearch(&th_v, det_ctx, p); + uint32_t r = PacketPatternSearch(det_ctx, p); if (r != 1) { printf("expected 1, got %"PRIu32": ", r); goto end; @@ -735,7 +735,7 @@ int DetectFastPatternTest09(void) /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearch(&th_v, det_ctx, p) == 0) + if (PacketPatternSearch(det_ctx, p) == 0) result = 1; SigGroupCleanup(de_ctx); @@ -791,7 +791,7 @@ int DetectFastPatternTest10(void) /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = PacketPatternSearch(&th_v, det_ctx, p); + uint32_t r = PacketPatternSearch(det_ctx, p); if (r != 1) { printf("expected 1, got %"PRIu32": ", r); goto end; @@ -845,7 +845,7 @@ int DetectFastPatternTest11(void) /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearch(&th_v, det_ctx, p) == 0) + if (PacketPatternSearch(det_ctx, p) == 0) result = 1; @@ -897,7 +897,7 @@ int DetectFastPatternTest12(void) /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearch(&th_v, det_ctx, p) == 0) + if (PacketPatternSearch(det_ctx, p) == 0) result = 1; SigGroupCleanup(de_ctx); @@ -954,7 +954,7 @@ int DetectFastPatternTest13(void) /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = PacketPatternSearch(&th_v, det_ctx, p); + uint32_t r = PacketPatternSearch(det_ctx, p); if (r != 1) { printf("expected 1 result, got %"PRIu32": ", r); goto end; diff --git a/src/detect.c b/src/detect.c index d0f32dcfae..b64d323d47 100644 --- a/src/detect.c +++ b/src/detect.c @@ -692,6 +692,15 @@ static void SigMatchSignaturesBuildMatchArray(DetectEngineCtx *de_ctx, } } + if (s->full_sig->flags & SIG_FLAG_MPM_URICONTENT) { + if (!(det_ctx->pmq.pattern_id_bitarray[(s->full_sig->mpm_uripattern_id / 8)] & + (1 << (s->full_sig->mpm_uripattern_id % 8)))) { + if (!(s->full_sig->flags & SIG_FLAG_MPM_URICONTENT_NEG)) { + continue; + } + } + } + /* de_state check, filter out all signatures that already had a match before * or just partially match */ if (s->flags & SIG_FLAG_AMATCH || s->flags & SIG_FLAG_UMATCH || @@ -863,6 +872,71 @@ end: #define SMS_USED_PM 0x02 #define SMS_USED_STREAM_PM 0x04 +static inline void RunMpmsOnFlow(DetectEngineCtx *de_ctx, + DetectEngineThreadCtx *det_ctx, + StreamMsg *smsg, Packet *p, uint8_t flags, + uint16_t alproto, void *alstate, + uint8_t *sms_runflags) +{ + uint32_t cnt = 0; + + /* have a look at the reassembled stream (if any) */ + if (p->flowflags & FLOW_PKT_ESTABLISHED) { + SCLogDebug("p->flowflags & FLOW_PKT_ESTABLISHED"); + if (smsg != NULL && det_ctx->sgh->mpm_stream_ctx != NULL) { + cnt = StreamPatternSearch(det_ctx, p, smsg, flags); + SCLogDebug("Stream Mpm cnt %u", cnt); + *sms_runflags |= SMS_USED_STREAM_PM; + } else { + SCLogDebug("smsg NULL (%p) or det_ctx->sgh->mpm_stream_ctx " + "NULL (%p)", smsg, det_ctx->sgh->mpm_stream_ctx); + } + } else { + SCLogDebug("NOT p->flowflags & FLOW_PKT_ESTABLISHED"); + } + + if (p->payload_len > 0 && det_ctx->sgh->mpm_ctx != NULL && + (!(p->flags & PKT_NOPAYLOAD_INSPECTION) && !(p->flags & PKT_STREAM_ADD))) { + + /* run the multi packet matcher against the payload of the packet */ + if (det_ctx->sgh->mpm_content_maxlen > p->payload_len) { + SCLogDebug("not mpm-inspecting as pkt payload is smaller than " + "the largest content length we need to match"); + } else { + SCLogDebug("search: (%p, maxlen %" PRIu32 ", sgh->sig_cnt %" PRIu32 ")", + det_ctx->sgh, det_ctx->sgh->mpm_content_maxlen, det_ctx->sgh->sig_cnt); + cnt = PacketPatternSearch(det_ctx, p); + SCLogDebug("post search: cnt %" PRIu32, cnt); + *sms_runflags |= SMS_USED_PM; + } + } + + if (alproto == ALPROTO_HTTP && alstate != NULL) { + if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_URI) { + cnt = DetectUricontentInspectMpm(det_ctx, p->flow, alstate); + SCLogDebug("uri search: cnt %" PRIu32, cnt); + } + //if (sgh->flags & SIG_GROUP_HEAD_MPM_HCBD) { + // cnt = DetectEngineInspectHttpClientBodyMpmInspect(de_ctx, det_ctx, + // f, htp_state); + // SCLogDebug("hcbd search: cnt %" PRIu32, cnt); + //} + //if (sgh->flags & SIG_GROUP_HEAD_MPM_HHD) { + // cnt = DetectEngineInspectHttpHeaderMpmInspect(det_ctx, f, + // htp_state); + // SCLogDebug("hhd search: cnt %" PRIu32, cnt); + //} + //if (sgh->flags & SIG_GROUP_HEAD_MPM_HHD) { + // cnt = DetectEngineInspectHttpRawHeaderMpmInspect(det_ctx, f, + // htp_state); + // SCLogDebug("hrhd search: cnt %" PRIu32, cnt); + //} + } + + return; +} + + /** * \brief Signature match function * @@ -879,7 +953,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh int fmatch = 0; uint32_t idx; - uint32_t cnt = 0; uint8_t flags = 0; /* flow/state flags */ void *alstate = NULL; @@ -1007,35 +1080,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh goto end; } - /* have a look at the reassembled stream (if any) */ - if (p->flowflags & FLOW_PKT_ESTABLISHED) { - SCLogDebug("p->flowflags & FLOW_PKT_ESTABLISHED"); - if (smsg != NULL && det_ctx->sgh->mpm_stream_ctx != NULL) { - cnt = StreamPatternSearch(th_v, det_ctx, p, smsg, flags); - SCLogDebug("cnt %u", cnt); - sms_runflags |= SMS_USED_STREAM_PM; - } else { - SCLogDebug("smsg NULL (%p) or det_ctx->sgh->mpm_stream_ctx NULL (%p)", smsg, det_ctx->sgh->mpm_stream_ctx); - } - } else { - SCLogDebug("NOT p->flowflags & FLOW_PKT_ESTABLISHED"); - } - - if (p->payload_len > 0 && det_ctx->sgh->mpm_ctx != NULL && - (!(p->flags & PKT_NOPAYLOAD_INSPECTION) && !(p->flags & PKT_STREAM_ADD))) - { - /* run the multi packet matcher against the payload of the packet */ - if (det_ctx->sgh->mpm_content_maxlen > p->payload_len) { - SCLogDebug("not mpm-inspecting as pkt payload is smaller than " - "the largest content length we need to match"); - } else { - SCLogDebug("search: (%p, maxlen %" PRIu32 ", sgh->sig_cnt %" PRIu32 ")", - det_ctx->sgh, det_ctx->sgh->mpm_content_maxlen, det_ctx->sgh->sig_cnt); - cnt = PacketPatternSearch(th_v, det_ctx, p); - SCLogDebug("post search: cnt %" PRIu32, cnt); - sms_runflags |= SMS_USED_PM; - } - } + RunMpmsOnFlow(de_ctx, det_ctx, smsg, p, flags, alproto, alstate, &sms_runflags); /* stateful app layer detection */ if (p->flags & PKT_HAS_FLOW && alstate != NULL) { diff --git a/src/detect.h b/src/detect.h index 66a3a976e5..86eb34d826 100644 --- a/src/detect.h +++ b/src/detect.h @@ -797,17 +797,23 @@ typedef struct SigTableElmt_ { char *name; } SigTableElmt; -#define SIG_GROUP_HAVECONTENT 0x0001 -#define SIG_GROUP_HAVEURICONTENT 0x0002 -#define SIG_GROUP_HAVESTREAMCONTENT 0x0004 -#define SIG_GROUP_HAVEHCBDCONTENT 0x0008 -#define SIG_GROUP_HAVEHHDCONTENT 0x0010 -#define SIG_GROUP_HAVEHRHDCONTENT 0x0020 -#define SIG_GROUP_HEAD_MPM_COPY 0x0040 -#define SIG_GROUP_HEAD_MPM_URI_COPY 0x0080 -#define SIG_GROUP_HEAD_MPM_STREAM_COPY 0x0100 -#define SIG_GROUP_HEAD_FREE 0x0200 -#define SIG_GROUP_HEAD_REFERENCED 0x0400 /**< sgh is being referenced by others, don't clear */ +#define SIG_GROUP_HAVECONTENT 0x00000001 +#define SIG_GROUP_HAVEURICONTENT 0x00000002 +#define SIG_GROUP_HAVESTREAMCONTENT 0x00000004 +#define SIG_GROUP_HAVEHCBDCONTENT 0x00000008 +#define SIG_GROUP_HAVEHHDCONTENT 0x00000010 +#define SIG_GROUP_HAVEHRHDCONTENT 0x00000020 +#define SIG_GROUP_HEAD_MPM_COPY 0x00000040 +#define SIG_GROUP_HEAD_MPM_URI_COPY 0x00000080 +#define SIG_GROUP_HEAD_MPM_STREAM_COPY 0x00000100 +#define SIG_GROUP_HEAD_FREE 0x00000200 +#define SIG_GROUP_HEAD_MPM_PACKET 0x00000400 +#define SIG_GROUP_HEAD_MPM_STREAM 0x00000800 +#define SIG_GROUP_HEAD_MPM_URI 0x00001000 +#define SIG_GROUP_HEAD_MPM_HCBD 0x00002000 +#define SIG_GROUP_HEAD_MPM_HHD 0x00004000 +#define SIG_GROUP_HEAD_MPM_HRHD 0x00008000 +#define SIG_GROUP_HEAD_REFERENCED 0x00010000 /**< sgh is being referenced by others, don't clear */ typedef struct SigGroupHeadInitData_ { /* list of content containers @@ -833,12 +839,11 @@ typedef struct SigGroupHeadInitData_ { /** \brief Container for matching data for a signature group */ typedef struct SigGroupHead_ { - uint16_t flags; + uint32_t flags; /* number of sigs in this head */ SigIntId sig_cnt; uint16_t mpm_content_maxlen; - uint16_t mpm_streamcontent_maxlen; /** chunk of memory containing the "header" part of each * signature ordered as an array. Used to pre-filter the @@ -852,8 +857,9 @@ typedef struct SigGroupHead_ { MpmCtx *mpm_hcbd_ctx; MpmCtx *mpm_hhd_ctx; MpmCtx *mpm_hrhd_ctx; + + uint16_t mpm_streamcontent_maxlen; uint16_t mpm_uricontent_maxlen; - uint16_t pad1; #if __WORDSIZE == 64 uint32_t pad2; #endif