From b140ed1c9c395d7014564ce077e4dd3b4ae5304e Mon Sep 17 00:00:00 2001 From: Anoop Saldanha Date: Tue, 7 Dec 2010 19:22:06 +0530 Subject: [PATCH] modify detection engine to run hhd mpm before building the match array --- src/detect-engine-hcbd.c | 22 +++-- src/detect-engine-hhd.c | 168 +++++++++++++++++++++------------------ src/detect-engine-hhd.h | 5 ++ src/detect-uricontent.c | 5 ++ src/detect.c | 24 ++++-- 5 files changed, 131 insertions(+), 93 deletions(-) diff --git a/src/detect-engine-hcbd.c b/src/detect-engine-hcbd.c index 30bcc8bee7..19744cb24e 100644 --- a/src/detect-engine-hcbd.c +++ b/src/detect-engine-hcbd.c @@ -267,6 +267,14 @@ void DetectEngineBufferHttpClientBodies(DetectEngineCtx *de_ctx, htp_tx_t *tx = NULL; int i = 0; + /* locking the flow, we will inspect the htp state */ + SCMutexLock(&f->m); + + if (htp_state->connp == NULL || htp_state->connp->conn == NULL) { + SCLogDebug("HTP state has no conn(p)"); + goto end; + } + /* it is either the first entry into this function. If it is not, * then we just don't have any http transactions */ if (det_ctx->hcbd_buffers_list_len == 0) { @@ -274,31 +282,31 @@ void DetectEngineBufferHttpClientBodies(DetectEngineCtx *de_ctx, int tmp_idx = AppLayerTransactionGetInspectId(f); /* error! get out of here */ if (tmp_idx == -1) - return; + goto end; /* let's get the transaction count. We need this to hold the client body * buffer for each transaction */ det_ctx->hcbd_buffers_list_len = list_size(htp_state->connp->conn->transactions) - tmp_idx; /* no transactions?! cool. get out of here */ if (det_ctx->hcbd_buffers_list_len == 0) - return; + goto end; /* assign space to hold buffers. Each per transaction */ det_ctx->hcbd_buffers = SCMalloc(det_ctx->hcbd_buffers_list_len * sizeof(uint8_t *)); if (det_ctx->hcbd_buffers == NULL) { - return; + goto end; } memset(det_ctx->hcbd_buffers, 0, det_ctx->hcbd_buffers_list_len * sizeof(uint8_t *)); det_ctx->hcbd_buffers_len = SCMalloc(det_ctx->hcbd_buffers_list_len * sizeof(uint32_t)); if (det_ctx->hcbd_buffers_len == NULL) { - return; + goto end; } memset(det_ctx->hcbd_buffers_len, 0, det_ctx->hcbd_buffers_list_len * sizeof(uint32_t)); } else { /* we already have the buffer space alloted. Get out of there */ - return; + goto end; } for (idx = AppLayerTransactionGetInspectId(f); @@ -347,7 +355,7 @@ void DetectEngineBufferHttpClientBodies(DetectEngineCtx *de_ctx, chunks_buffer_len += cur->len; if ( (chunks_buffer = SCRealloc(chunks_buffer, chunks_buffer_len)) == NULL) { - return; + goto end; } memcpy(chunks_buffer + chunks_buffer_len - cur->len, cur->data, cur->len); @@ -360,6 +368,8 @@ void DetectEngineBufferHttpClientBodies(DetectEngineCtx *de_ctx, } /* else - if (htud->body.nchunks == 0) */ } /* for (idx = AppLayerTransactionGetInspectId(f); .. */ + end: + SCMutexUnlock(&f->m); return; } diff --git a/src/detect-engine-hhd.c b/src/detect-engine-hhd.c index 72e29e0267..b4d2ec046f 100644 --- a/src/detect-engine-hhd.c +++ b/src/detect-engine-hhd.c @@ -255,35 +255,62 @@ match: * stores them away in detection context. Also calls the mpm on the * buffers. * + * \param de_ctx Detection engine ctx. * \param det_ctx Detection engine thread ctx. * \param f Pointer to the locked flow. * \param htp_state http state. * - * \retval cnt The match count from the mpm call. - * * \warning Make sure flow is locked. */ -static uint32_t DetectEngineInspectHttpHeaderMpmInspect(DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, - HtpState *htp_state) +void DetectEngineBufferHttpHeaders(DetectEngineThreadCtx *det_ctx, Flow *f, + HtpState *htp_state) { - uint32_t cnt = 0; size_t idx = 0; htp_tx_t *tx = NULL; int i = 0; - for (idx = AppLayerTransactionGetInspectId(f); - i < det_ctx->hhd_buffers_list_len; idx++, i++) { + /* locking the flow, we will inspect the htp state */ + SCMutexLock(&f->m); - /* if the buffer already exists, use it */ - if (det_ctx->hhd_buffers[i] != NULL) { - if (s->mpm_flags & SIG_FLAG_MPM_HHDCONTENT) { - cnt += HttpHeaderPatternSearch(det_ctx, - det_ctx->hhd_buffers[i], - det_ctx->hhd_buffers_len[i]); - } - continue; + if (htp_state->connp == NULL || htp_state->connp->conn == NULL) { + SCLogDebug("HTP state has no conn(p)"); + goto end; + } + + /* it is either the first entry into this function. If it is not, + * then we just don't have any http transactions */ + if (det_ctx->hhd_buffers_list_len == 0) { + /* get the transaction id */ + int tmp_idx = AppLayerTransactionGetInspectId(f); + /* error! get out of here */ + if (tmp_idx == -1) + goto end; + + /* let's get the transaction count. We need this to hold the header + * buffer for each transaction */ + det_ctx->hhd_buffers_list_len = list_size(htp_state->connp->conn->transactions) - tmp_idx; + /* no transactions?! cool. get out of here */ + if (det_ctx->hhd_buffers_list_len == 0) + goto end; + + /* assign space to hold buffers. Each per transaction */ + det_ctx->hhd_buffers = SCMalloc(det_ctx->hhd_buffers_list_len * sizeof(uint8_t *)); + if (det_ctx->hhd_buffers == NULL) { + goto end; + } + memset(det_ctx->hhd_buffers, 0, det_ctx->hhd_buffers_list_len * sizeof(uint8_t *)); + + det_ctx->hhd_buffers_len = SCMalloc(det_ctx->hhd_buffers_list_len * sizeof(uint32_t)); + if (det_ctx->hhd_buffers_len == NULL) { + goto end; } + memset(det_ctx->hhd_buffers_len, 0, det_ctx->hhd_buffers_list_len * sizeof(uint32_t)); + } else { + goto end; + } /* else - if (det_ctx->hhd_buffers_list_len == 0) */ + + for (idx = AppLayerTransactionGetInspectId(f); + i < det_ctx->hhd_buffers_list_len; idx++, i++) { tx = list_get(htp_state->connp->conn->transactions, idx); if (tx == NULL) @@ -321,12 +348,25 @@ static uint32_t DetectEngineInspectHttpHeaderMpmInspect(DetectEngineThreadCtx *d det_ctx->hhd_buffers[i] = headers_buffer; det_ctx->hhd_buffers_len[i] = headers_buffer_len; - /* carry out the mpm */ - if (s->mpm_flags & SIG_FLAG_MPM_HHDCONTENT) - cnt += HttpHeaderPatternSearch(det_ctx, headers_buffer, headers_buffer_len); } /* for (idx = AppLayerTransactionGetInspectId(f); .. */ - SCReturnUInt(cnt); + end: + SCMutexUnlock(&f->m); + return; +} + +int DetectEngineRunHttpHeaderMpm(DetectEngineThreadCtx *det_ctx) +{ + int i; + uint32_t cnt = 0; + + for (i = 0; i < det_ctx->hhd_buffers_list_len; i++) { + cnt += HttpHeaderPatternSearch(det_ctx, + det_ctx->hhd_buffers[i], + det_ctx->hhd_buffers_len[i]); + } + + return cnt; } /** @@ -366,65 +406,35 @@ int DetectEngineInspectHttpHeader(DetectEngineCtx *de_ctx, goto end; } - /* it is either the first entry into this function. If it is not, - * then we just don't have any http transactions */ - if (det_ctx->hhd_buffers_list_len == 0) { - /* get the transaction id */ - int tmp_idx = AppLayerTransactionGetInspectId(f); - /* error! get out of here */ - if (tmp_idx == -1) - goto end; - - /* let's get the transaction count. We need this to hold the header - * buffer for each transaction */ - det_ctx->hhd_buffers_list_len = list_size(htp_state->connp->conn->transactions) - tmp_idx; - /* no transactions?! cool. get out of here */ - if (det_ctx->hhd_buffers_list_len == 0) - goto end; - - /* assign space to hold buffers. Each per transaction */ - det_ctx->hhd_buffers = SCMalloc(det_ctx->hhd_buffers_list_len * sizeof(uint8_t *)); - if (det_ctx->hhd_buffers == NULL) { - r = 0; - goto end; - } - memset(det_ctx->hhd_buffers, 0, det_ctx->hhd_buffers_list_len * sizeof(uint8_t *)); - - det_ctx->hhd_buffers_len = SCMalloc(det_ctx->hhd_buffers_list_len * sizeof(uint32_t)); - if (det_ctx->hhd_buffers_len == NULL) { - r = 0; - goto end; - } - memset(det_ctx->hhd_buffers_len, 0, det_ctx->hhd_buffers_list_len * sizeof(uint32_t)); - } /* if (det_ctx->hhd_buffers_list_len == 0) */ - - if (s->mpm_flags & SIG_FLAG_MPM_HHDCONTENT) { - if (det_ctx->de_mpm_scanned_hhd == FALSE) { - uint32_t cnt = DetectEngineInspectHttpHeaderMpmInspect(det_ctx, s, - f, htp_state); - if (cnt <= 0) - det_ctx->de_have_hhd = FALSE; - - det_ctx->de_mpm_scanned_hhd = TRUE; - } - } else { - DetectEngineInspectHttpHeaderMpmInspect(det_ctx, s, f, htp_state); - } - - if (det_ctx->de_have_hhd == FALSE && - s->mpm_flags & SIG_FLAG_MPM_HHDCONTENT && - !(s->mpm_flags & SIG_FLAG_MPM_HHDCONTENT_NEG)) { - SCLogDebug("mpm results failure for http headers. Get out of here"); - goto end; - } - - if ((s->mpm_flags & SIG_FLAG_MPM_HHDCONTENT) && (det_ctx->de_mpm_scanned_hhd == TRUE)) { - /* filter out the sig that needs a match, but have no matches */ - if (!(s->mpm_flags & SIG_FLAG_MPM_HHDCONTENT_NEG) && - !(det_ctx->pmq.pattern_id_bitarray[(s->mpm_hhdpattern_id / 8)] & (1 << (s->mpm_hhdpattern_id % 8)))) { - goto end; - } - } + DetectEngineBufferHttpHeaders(det_ctx, f, htp_state); + + //if (s->mpm_flags & SIG_FLAG_MPM_HHDCONTENT) { + // if (det_ctx->de_mpm_scanned_hhd == FALSE) { + // uint32_t cnt = DetectEngineInspectHttpHeaderMpmInspect(det_ctx, s, + // f, htp_state); + // if (cnt <= 0) + // det_ctx->de_have_hhd = FALSE; + // + // det_ctx->de_mpm_scanned_hhd = TRUE; + // } + //} else { + // DetectEngineInspectHttpHeaderMpmInspect(det_ctx, s, f, htp_state); + //} + + //if (det_ctx->de_have_hhd == FALSE && + // s->mpm_flags & SIG_FLAG_MPM_HHDCONTENT && + // !(s->mpm_flags & SIG_FLAG_MPM_HHDCONTENT_NEG)) { + // SCLogDebug("mpm results failure for http headers. Get out of here"); + // goto end; + //} + + //if ((s->mpm_flags & SIG_FLAG_MPM_HHDCONTENT) && (det_ctx->de_mpm_scanned_hhd == TRUE)) { + // /* filter out the sig that needs a match, but have no matches */ + // if (!(s->mpm_flags & SIG_FLAG_MPM_HHDCONTENT_NEG) && + // !(det_ctx->pmq.pattern_id_bitarray[(s->mpm_hhdpattern_id / 8)] & (1 << (s->mpm_hhdpattern_id % 8)))) { + // goto end; + // } + //} for (i = 0; i < det_ctx->hhd_buffers_list_len; i++) { uint8_t *hhd_buffer = det_ctx->hhd_buffers[i]; diff --git a/src/detect-engine-hhd.h b/src/detect-engine-hhd.h index f0186a234e..07b6a3ccc6 100644 --- a/src/detect-engine-hhd.h +++ b/src/detect-engine-hhd.h @@ -23,6 +23,11 @@ #ifndef __DETECT_ENGINE_HHD_H__ #define __DETECT_ENGINE_HHD_H__ +#include "app-layer-htp.h" + +void DetectEngineBufferHttpHeaders(DetectEngineThreadCtx *, Flow *, + HtpState *); +int DetectEngineRunHttpHeaderMpm(DetectEngineThreadCtx *); int DetectEngineInspectHttpHeader(DetectEngineCtx *, DetectEngineThreadCtx *, Signature *, Flow *, uint8_t, void *); void DetectEngineCleanHHDBuffers(DetectEngineThreadCtx *); diff --git a/src/detect-uricontent.c b/src/detect-uricontent.c index 8f0190b90a..7336b00097 100644 --- a/src/detect-uricontent.c +++ b/src/detect-uricontent.c @@ -469,8 +469,12 @@ uint32_t DetectUricontentInspectMpm(DetectEngineThreadCtx *det_ctx, Flow *f, Htp size_t idx = 0; htp_tx_t *tx = NULL; + /* locking the flow, we will inspect the htp state */ + SCMutexLock(&f->m); + if (htp_state == NULL || htp_state->connp == NULL) { SCLogDebug("no HTTP state / no connp"); + SCMutexUnlock(&f->m); SCReturnUInt(0U); } @@ -486,6 +490,7 @@ uint32_t DetectUricontentInspectMpm(DetectEngineThreadCtx *det_ctx, Flow *f, Htp bstr_len(tx->request_uri_normalized)); } + SCMutexUnlock(&f->m); SCReturnUInt(cnt); } diff --git a/src/detect.c b/src/detect.c index 1e2dcbdc2c..c037bf9dde 100644 --- a/src/detect.c +++ b/src/detect.c @@ -710,6 +710,15 @@ static void SigMatchSignaturesBuildMatchArray(DetectEngineCtx *de_ctx, } } + if (s->full_sig->mpm_flags & SIG_FLAG_MPM_HHDCONTENT) { + if (!(det_ctx->pmq.pattern_id_bitarray[(s->full_sig->mpm_hhdpattern_id / 8)] & + (1 << (s->full_sig->mpm_hhdpattern_id % 8)))) { + if (!(s->full_sig->mpm_flags & SIG_FLAG_MPM_HHDCONTENT_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 || @@ -930,12 +939,11 @@ static inline void RunMpmsOnFlow(DetectEngineCtx *de_ctx, cnt = DetectEngineRunHttpClientBodyMpm(det_ctx); 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 (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HHD) { + DetectEngineBufferHttpHeaders(det_ctx, p->flow, alstate); + cnt = DetectEngineRunHttpHeaderMpm(det_ctx); + SCLogDebug("hhd search: cnt %" PRIu32, cnt); + } //if (sgh->flags & SIG_GROUP_HEAD_MPM_HHD) { // cnt = DetectEngineInspectHttpRawHeaderMpmInspect(det_ctx, f, // htp_state); @@ -973,8 +981,8 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh //det_ctx->de_have_hcbd = TRUE; //det_ctx->de_mpm_scanned_hcbd = FALSE; - det_ctx->de_have_hhd = TRUE; - det_ctx->de_mpm_scanned_hhd = FALSE; + //det_ctx->de_have_hhd = TRUE; + //det_ctx->de_mpm_scanned_hhd = FALSE; det_ctx->de_have_hrhd = TRUE; det_ctx->de_mpm_scanned_hrhd = FALSE;