From 9a5c666b2659cba6eef20c6721d572f5c7991a43 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sat, 11 Sep 2021 09:47:31 +0200 Subject: [PATCH] detect/http: clean up header buffer logic Simplify and clean up header buffer management. The code was designed to track buffers for several transactions in parallel, from when the detection engine wasn't aware of transactions. For http.start and http.header_names use generic mpm and inspect functions. --- src/detect-http-header-common.c | 104 +------------ src/detect-http-header-common.h | 13 +- src/detect-http-header-names.c | 259 ++++---------------------------- src/detect-http-header.c | 24 +-- src/detect-http-start.c | 231 +++------------------------- 5 files changed, 67 insertions(+), 564 deletions(-) diff --git a/src/detect-http-header-common.c b/src/detect-http-header-common.c index 2495d057e7..3a8fe08c05 100644 --- a/src/detect-http-header-common.c +++ b/src/detect-http-header-common.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2017 Open Information Security Foundation +/* Copyright (C) 2007-2021 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -56,27 +56,19 @@ #include "detect-http-header-common.h" -static inline int CreateSpace(HttpHeaderThreadData *td, uint64_t size); - void *HttpHeaderThreadDataInit(void *data) { HttpHeaderThreadData *td = SCCalloc(1, sizeof(*td)); if (td != NULL) { if (data == NULL) { - td->tx_step = 4; td->size_step = 512; } else { HttpHeaderThreadDataConfig *c = data; - td->tx_step = c->tx_step; td->size_step = c->size_step; } /* initialize minimal buffers */ - (void)CreateSpace(td, 1); - int i; - for (i = 0; i < td->buffers_size; i++) { - (void)HttpHeaderExpandBuffer(td, &td->buffers[i], 1); - } + (void)HttpHeaderExpandBuffer(td, &td->buffer, 1); } return td; } @@ -84,59 +76,10 @@ void *HttpHeaderThreadDataInit(void *data) void HttpHeaderThreadDataFree(void *data) { HttpHeaderThreadData *hdrnames = data; - - int i; - for (i = 0; i < hdrnames->buffers_size; i++) { - if (hdrnames->buffers[i].buffer) - SCFree(hdrnames->buffers[i].buffer); - if (hdrnames->buffers[i].size) { - SCLogDebug("hdrnames->buffers[%d].size %u (%u)", - i, hdrnames->buffers[i].size, hdrnames->buffers_size); - } - } - SCFree(hdrnames->buffers); + SCFree(hdrnames->buffer.buffer); SCFree(hdrnames); } -static void Reset(HttpHeaderThreadData *hdrnames, uint64_t tick) -{ - uint16_t i; - for (i = 0; i < hdrnames->buffers_list_len; i++) { - hdrnames->buffers[i].len = 0; - } - hdrnames->buffers_list_len = 0; - hdrnames->start_tx_id = 0; - hdrnames->tick = tick; -} - -static inline int CreateSpace(HttpHeaderThreadData *td, uint64_t size) -{ - if (size >= SHRT_MAX) - return -1; - - if (size > td->buffers_size) { - uint16_t extra = td->tx_step; - while (td->buffers_size + extra < size) { - extra += td->tx_step; - } - SCLogDebug("adding %u to the buffer", extra); - - void *ptmp = SCRealloc(td->buffers, - (td->buffers_size + extra) * sizeof(HttpHeaderBuffer)); - if (ptmp == NULL) { - SCFree(td->buffers); - td->buffers = NULL; - td->buffers_size = 0; - td->buffers_list_len = 0; - return -1; - } - td->buffers = ptmp; - memset(td->buffers + td->buffers_size, 0, extra * sizeof(HttpHeaderBuffer)); - td->buffers_size += extra; - } - return 0; -} - int HttpHeaderExpandBuffer(HttpHeaderThreadData *td, HttpHeaderBuffer *buf, uint32_t size) { @@ -156,51 +99,18 @@ int HttpHeaderExpandBuffer(HttpHeaderThreadData *td, return 0; } -HttpHeaderBuffer *HttpHeaderGetBufferSpaceForTXID(DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, uint64_t tx_id, const int keyword_id, - HttpHeaderThreadData **ret_hdr_td) +HttpHeaderBuffer *HttpHeaderGetBufferSpace(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, + const int keyword_id, HttpHeaderThreadData **ret_hdr_td) { - int index = 0; *ret_hdr_td = NULL; HttpHeaderThreadData *hdr_td = DetectThreadCtxGetGlobalKeywordThreadCtx(det_ctx, keyword_id); if (hdr_td == NULL) return NULL; - if (hdr_td->tick != det_ctx->ticker) - Reset(hdr_td, det_ctx->ticker); *ret_hdr_td = hdr_td; - if (hdr_td->buffers_list_len == 0) { - /* get the inspect id to use as a 'base id' */ - uint64_t base_inspect_id = AppLayerParserGetTransactionInspectId(f->alparser, flags); - BUG_ON(base_inspect_id > tx_id); - /* see how many space we need for the current tx_id */ - uint64_t txs = (tx_id - base_inspect_id) + 1; - if (CreateSpace(hdr_td, txs) < 0) - return NULL; - - index = (tx_id - base_inspect_id); - hdr_td->start_tx_id = base_inspect_id; - hdr_td->buffers_list_len = txs; - } else { - /* tx fits in our current buffers */ - if ((tx_id - hdr_td->start_tx_id) < hdr_td->buffers_list_len) { - /* if we previously reassembled, return that buffer */ - if (hdr_td->buffers[(tx_id - hdr_td->start_tx_id)].len != 0) { - return &hdr_td->buffers[(tx_id - hdr_td->start_tx_id)]; - } - /* otherwise fall through */ - } else { - /* not enough space, lets expand */ - uint64_t txs = (tx_id - hdr_td->start_tx_id) + 1; - if (CreateSpace(hdr_td, txs) < 0) - return NULL; - - hdr_td->buffers_list_len = txs; - } - index = (tx_id - hdr_td->start_tx_id); - } - HttpHeaderBuffer *buf = &hdr_td->buffers[index]; + HttpHeaderBuffer *buf = &hdr_td->buffer; + buf->len = 0; return buf; } diff --git a/src/detect-http-header-common.h b/src/detect-http-header-common.h index c6fc5c684b..a9c830e2a2 100644 --- a/src/detect-http-header-common.h +++ b/src/detect-http-header-common.h @@ -31,26 +31,19 @@ typedef struct HttpHeaderBuffer_ { } HttpHeaderBuffer; typedef struct HttpHeaderThreadConfig_ { - uint16_t tx_step; uint16_t size_step; } HttpHeaderThreadDataConfig; typedef struct HttpHeaderThreadData_ { - HttpHeaderBuffer *buffers; /**< array of buffers */ - uint16_t buffers_size; /**< number of buffers */ - uint16_t buffers_list_len; + HttpHeaderBuffer buffer; /**< array of buffers */ uint16_t size_step; /**< increase size of HttpHeaderBuffer::buffer with this */ - uint16_t tx_step; /**< increase number of txs with this */ - uint64_t start_tx_id; - uint64_t tick; } HttpHeaderThreadData; void *HttpHeaderThreadDataInit(void *data); void HttpHeaderThreadDataFree(void *data); -HttpHeaderBuffer *HttpHeaderGetBufferSpaceForTXID(DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, uint64_t tx_id, const int keyword_id, - HttpHeaderThreadData **ret_hdr_td); +HttpHeaderBuffer *HttpHeaderGetBufferSpace(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, + const int keyword_id, HttpHeaderThreadData **ret_hdr_td); int HttpHeaderExpandBuffer(HttpHeaderThreadData *td, HttpHeaderBuffer *buf, uint32_t size); diff --git a/src/detect-http-header-names.c b/src/detect-http-header-names.c index bc6115e170..717178e948 100644 --- a/src/detect-http-header-names.c +++ b/src/detect-http-header-names.c @@ -73,25 +73,19 @@ static int g_buffer_id = 0; static int g_keyword_thread_id = 0; -#define BUFFER_TX_STEP 4 #define BUFFER_SIZE_STEP 256 -static HttpHeaderThreadDataConfig g_td_config = { BUFFER_TX_STEP, BUFFER_SIZE_STEP }; +static HttpHeaderThreadDataConfig g_td_config = { BUFFER_SIZE_STEP }; -static uint8_t *GetBufferForTX(htp_tx_t *tx, uint64_t tx_id, - DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, uint32_t *buffer_len) +static uint8_t *GetBufferForTX( + htp_tx_t *tx, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, uint32_t *buffer_len) { *buffer_len = 0; HttpHeaderThreadData *hdr_td = NULL; - HttpHeaderBuffer *buf = HttpHeaderGetBufferSpaceForTXID(det_ctx, f, flags, - tx_id, g_keyword_thread_id, &hdr_td); + HttpHeaderBuffer *buf = + HttpHeaderGetBufferSpace(det_ctx, f, flags, g_keyword_thread_id, &hdr_td); if (unlikely(buf == NULL)) { return NULL; - } else if (buf->len > 0) { - /* already filled buf, reuse */ - *buffer_len = buf->len; - return buf->buffer; } htp_table_t *headers; @@ -150,238 +144,43 @@ static uint8_t *GetBufferForTX(htp_tx_t *tx, uint64_t tx_id, return buf->buffer; } -static InspectionBuffer *GetBuffer2ForTX(DetectEngineThreadCtx *det_ctx, - const DetectEngineTransforms *transforms, Flow *_f, const uint8_t flow_flags, void *txv, +static InspectionBuffer *GetBuffer1ForTX(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, const int list_id) { - InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); - if (buffer->inspect == NULL) { - uint32_t b_len = 0; - const uint8_t *b = NULL; - - if (rs_http2_tx_get_header_names(txv, flow_flags, &b, &b_len) != 1) - return NULL; - if (b == NULL || b_len == 0) - return NULL; - - InspectionBufferSetup(det_ctx, list_id, buffer, b, b_len); - InspectionBufferApplyTransforms(buffer, transforms); - } - - return buffer; -} - -typedef struct PrefilterMpmHttpHeaderCtx { - int list_id; - const MpmCtx *mpm_ctx; - const DetectEngineTransforms *transforms; -} PrefilterMpmHttpHeaderCtx; - -/** \brief HTTP Headers Mpm prefilter callback - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * \param f flow to inspect - * \param txv tx to inspect - * \param pectx inspection context - */ -static void PrefilterTxHttpRequestHeaderNames(DetectEngineThreadCtx *det_ctx, - const void *pectx, - Packet *p, Flow *f, void *txv, - const uint64_t idx, const uint8_t flags) -{ - SCEnter(); - - htp_tx_t *tx = (htp_tx_t *)txv; - if (tx->request_headers == NULL) - return; - - const PrefilterMpmHttpHeaderCtx *ctx = pectx; - const MpmCtx *mpm_ctx = ctx->mpm_ctx; - SCLogDebug("running on list %d", ctx->list_id); - - const int list_id = ctx->list_id; - InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); - if (buffer->inspect == NULL) { - uint32_t rawdata_len = 0; - uint8_t *rawdata = GetBufferForTX(txv, idx, det_ctx, - f, flags, &rawdata_len); - if (rawdata_len == 0) - return; - - /* setup buffer and apply transforms */ - InspectionBufferSetup(det_ctx, list_id, buffer, rawdata, rawdata_len); - InspectionBufferApplyTransforms(buffer, ctx->transforms); - } - - const uint32_t data_len = buffer->inspect_len; - const uint8_t *data = buffer->inspect; - - SCLogDebug("mpm'ing buffer:"); - //PrintRawDataFp(stdout, data, data_len); - - if (data != NULL && data_len >= mpm_ctx->minlen) { - (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, - &det_ctx->mtcu, &det_ctx->pmq, data, data_len); - } -} - -static void PrefilterMpmHttpHeaderFree(void *ptr) -{ - SCFree(ptr); -} - -static int PrefilterTxHttpRequestHeaderNamesRegister(DetectEngineCtx *de_ctx, - SigGroupHead *sgh, MpmCtx *mpm_ctx, - const DetectBufferMpmRegistery *mpm_reg, int list_id) -{ - SCEnter(); - - PrefilterMpmHttpHeaderCtx *pectx = SCCalloc(1, sizeof(*pectx)); - if (pectx == NULL) - return -1; - pectx->list_id = list_id; - pectx->mpm_ctx = mpm_ctx; - pectx->transforms = &mpm_reg->transforms; - - int r = PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxHttpRequestHeaderNames, - mpm_reg->app_v2.alproto, HTP_REQUEST_HEADERS, - pectx, PrefilterMpmHttpHeaderFree, mpm_reg->pname); - if (r != 0) { - SCFree(pectx); - return r; - } - - return r; -} - -/** \brief HTTP Headers Mpm prefilter callback - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * \param f flow to inspect - * \param txv tx to inspect - * \param pectx inspection context - */ -static void PrefilterTxHttpResponseHeaderNames(DetectEngineThreadCtx *det_ctx, - const void *pectx, - Packet *p, Flow *f, void *txv, - const uint64_t idx, const uint8_t flags) -{ - SCEnter(); - - htp_tx_t *tx = (htp_tx_t *)txv; - if (tx->response_headers == NULL) - return; - - const PrefilterMpmHttpHeaderCtx *ctx = pectx; - const MpmCtx *mpm_ctx = ctx->mpm_ctx; - SCLogDebug("running on list %d", ctx->list_id); - - const int list_id = ctx->list_id; InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); if (buffer->inspect == NULL) { uint32_t rawdata_len = 0; - uint8_t *rawdata = GetBufferForTX(txv, idx, det_ctx, - f, flags, &rawdata_len); + uint8_t *rawdata = GetBufferForTX(txv, det_ctx, f, flow_flags, &rawdata_len); if (rawdata_len == 0) - return; + return NULL; - /* setup buffer and apply transforms */ InspectionBufferSetup(det_ctx, list_id, buffer, rawdata, rawdata_len); - InspectionBufferApplyTransforms(buffer, ctx->transforms); - } - - const uint32_t data_len = buffer->inspect_len; - const uint8_t *data = buffer->inspect; - - SCLogDebug("mpm'ing buffer:"); - //PrintRawDataFp(stdout, data, data_len); - - if (data != NULL && data_len >= mpm_ctx->minlen) { - (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, - &det_ctx->mtcu, &det_ctx->pmq, data, data_len); - } -} - -static int PrefilterTxHttpResponseHeaderNamesRegister(DetectEngineCtx *de_ctx, - SigGroupHead *sgh, MpmCtx *mpm_ctx, - const DetectBufferMpmRegistery *mpm_reg, int list_id) -{ - SCEnter(); - - PrefilterMpmHttpHeaderCtx *pectx = SCCalloc(1, sizeof(*pectx)); - if (pectx == NULL) - return -1; - pectx->list_id = list_id; - pectx->mpm_ctx = mpm_ctx; - pectx->transforms = &mpm_reg->transforms; - - int r = PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxHttpResponseHeaderNames, - mpm_reg->app_v2.alproto, HTP_RESPONSE_HEADERS, - pectx, PrefilterMpmHttpHeaderFree, mpm_reg->pname); - if (r != 0) { - SCFree(pectx); - return r; + InspectionBufferApplyTransforms(buffer, transforms); } - return r; + return buffer; } -static int InspectEngineHttpHeaderNames( - DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - const DetectEngineAppInspectionEngine *engine, - const Signature *s, - Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id) +static InspectionBuffer *GetBuffer2ForTX(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, Flow *_f, const uint8_t flow_flags, void *txv, + const int list_id) { - const int list_id = engine->sm_list; InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); if (buffer->inspect == NULL) { - SCLogDebug("setting up inspect buffer %d", list_id); + uint32_t b_len = 0; + const uint8_t *b = NULL; - /* if prefilter didn't already run, we need to consider transformations */ - const DetectEngineTransforms *transforms = NULL; - if (!engine->mpm) { - transforms = engine->v2.transforms; - } + if (rs_http2_tx_get_header_names(txv, flow_flags, &b, &b_len) != 1) + return NULL; + if (b == NULL || b_len == 0) + return NULL; - uint32_t rawdata_len = 0; - uint8_t *rawdata = GetBufferForTX(txv, tx_id, det_ctx, - f, flags, &rawdata_len); - if (rawdata_len == 0) { - SCLogDebug("no data"); - goto end; - } - /* setup buffer and apply transforms */ - InspectionBufferSetup(det_ctx, list_id, buffer, rawdata, rawdata_len); + InspectionBufferSetup(det_ctx, list_id, buffer, b, b_len); InspectionBufferApplyTransforms(buffer, transforms); } - const uint32_t data_len = buffer->inspect_len; - const uint8_t *data = buffer->inspect; - const uint64_t offset = buffer->inspect_offset; - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, - NULL, f, (uint8_t *)data, data_len, offset, - DETECT_CI_FLAGS_SINGLE, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - - end: - if (flags & STREAM_TOSERVER) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP1, txv, flags) > - HTP_REQUEST_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } else { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP1, txv, flags) > - HTP_RESPONSE_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; + return buffer; } /** @@ -421,16 +220,18 @@ void DetectHttpHeaderNamesRegister(void) sigmatch_table[DETECT_AL_HTTP_HEADER_NAMES].flags |= SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER; - DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, - PrefilterTxHttpRequestHeaderNamesRegister, NULL, ALPROTO_HTTP1, HTP_REQUEST_HEADERS); - DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2, - PrefilterTxHttpResponseHeaderNamesRegister, NULL, ALPROTO_HTTP1, HTP_RESPONSE_HEADERS); + /* http1 */ + DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister, + GetBuffer1ForTX, ALPROTO_HTTP1, HTP_REQUEST_HEADERS); + DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister, + GetBuffer1ForTX, ALPROTO_HTTP1, HTP_RESPONSE_HEADERS); DetectAppLayerInspectEngineRegister2(BUFFER_NAME, ALPROTO_HTTP1, SIG_FLAG_TOSERVER, - HTP_REQUEST_HEADERS, InspectEngineHttpHeaderNames, NULL); + HTP_REQUEST_HEADERS, DetectEngineInspectBufferGeneric, GetBuffer1ForTX); DetectAppLayerInspectEngineRegister2(BUFFER_NAME, ALPROTO_HTTP1, SIG_FLAG_TOCLIENT, - HTP_RESPONSE_HEADERS, InspectEngineHttpHeaderNames, NULL); + HTP_RESPONSE_HEADERS, DetectEngineInspectBufferGeneric, GetBuffer1ForTX); + /* http2 */ DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister, GetBuffer2ForTX, ALPROTO_HTTP2, HTTP2StateDataClient); DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister, diff --git a/src/detect-http-header.c b/src/detect-http-header.c index 722de79363..bedee8f0c7 100644 --- a/src/detect-http-header.c +++ b/src/detect-http-header.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2018 Open Information Security Foundation +/* Copyright (C) 2007-2021 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -62,25 +62,19 @@ static void DetectHttpHeaderRegisterTests(void); static int g_http_header_buffer_id = 0; static int g_keyword_thread_id = 0; -#define BUFFER_TX_STEP 4 #define BUFFER_SIZE_STEP 1024 -static HttpHeaderThreadDataConfig g_td_config = { BUFFER_TX_STEP, BUFFER_SIZE_STEP }; +static HttpHeaderThreadDataConfig g_td_config = { BUFFER_SIZE_STEP }; -static uint8_t *GetBufferForTX(htp_tx_t *tx, uint64_t tx_id, - DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, uint32_t *buffer_len) +static uint8_t *GetBufferForTX( + htp_tx_t *tx, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, uint32_t *buffer_len) { *buffer_len = 0; HttpHeaderThreadData *hdr_td = NULL; - HttpHeaderBuffer *buf = HttpHeaderGetBufferSpaceForTXID(det_ctx, f, flags, - tx_id, g_keyword_thread_id, &hdr_td); + HttpHeaderBuffer *buf = + HttpHeaderGetBufferSpace(det_ctx, f, flags, g_keyword_thread_id, &hdr_td); if (unlikely(buf == NULL)) { return NULL; - } else if (buf->len > 0) { - /* already filled buf, reuse */ - *buffer_len = buf->len; - return buf->buffer; } htp_table_t *headers; @@ -192,8 +186,7 @@ static int DetectEngineInspectBufferHttpHeader( } uint32_t rawdata_len = 0; - uint8_t *rawdata = GetBufferForTX(txv, tx_id, det_ctx, - f, flags, &rawdata_len); + uint8_t *rawdata = GetBufferForTX(txv, det_ctx, f, flags, &rawdata_len); if (rawdata_len == 0) { SCLogDebug("no data"); goto end; @@ -262,8 +255,7 @@ static void PrefilterMpmHttpHeader(DetectEngineThreadCtx *det_ctx, InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); if (buffer->inspect == NULL) { uint32_t rawdata_len = 0; - uint8_t *rawdata = GetBufferForTX(txv, idx, det_ctx, - f, flags, &rawdata_len); + uint8_t *rawdata = GetBufferForTX(txv, det_ctx, f, flags, &rawdata_len); if (rawdata_len == 0) return; diff --git a/src/detect-http-start.c b/src/detect-http-start.c index 8aaa14e59f..3341d775b1 100644 --- a/src/detect-http-start.c +++ b/src/detect-http-start.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2019 Open Information Security Foundation +/* Copyright (C) 2007-2021 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -72,25 +72,19 @@ static int g_buffer_id = 0; static int g_keyword_thread_id = 0; -#define BUFFER_TX_STEP 4 #define BUFFER_SIZE_STEP 2048 -static HttpHeaderThreadDataConfig g_td_config = { BUFFER_TX_STEP, BUFFER_SIZE_STEP }; +static HttpHeaderThreadDataConfig g_td_config = { BUFFER_SIZE_STEP }; -static uint8_t *GetBufferForTX(htp_tx_t *tx, uint64_t tx_id, - DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, uint32_t *buffer_len) +static uint8_t *GetBufferForTX( + htp_tx_t *tx, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, uint32_t *buffer_len) { *buffer_len = 0; HttpHeaderThreadData *hdr_td = NULL; - HttpHeaderBuffer *buf = HttpHeaderGetBufferSpaceForTXID(det_ctx, f, flags, - tx_id, g_keyword_thread_id, &hdr_td); + HttpHeaderBuffer *buf = + HttpHeaderGetBufferSpace(det_ctx, f, flags, g_keyword_thread_id, &hdr_td); if (unlikely(buf == NULL)) { return NULL; - } else if (buf->len > 0) { - /* already filled buf, reuse */ - *buffer_len = buf->len; - return buf->buffer; } bstr *line = NULL; @@ -155,209 +149,22 @@ static uint8_t *GetBufferForTX(htp_tx_t *tx, uint64_t tx_id, return buf->buffer; } -typedef struct PrefilterMpmHttpStartCtx { - int list_id; - const MpmCtx *mpm_ctx; - const DetectEngineTransforms *transforms; -} PrefilterMpmHttpStartCtx; - -/** \brief HTTP Headers Mpm prefilter callback - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * \param f flow to inspect - * \param txv tx to inspect - * \param pectx inspection context - */ -static void PrefilterTxHttpRequestStart(DetectEngineThreadCtx *det_ctx, - const void *pectx, - Packet *p, Flow *f, void *txv, - const uint64_t idx, const uint8_t flags) +static InspectionBuffer *GetBuffer1ForTX(DetectEngineThreadCtx *det_ctx, + const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, + const int list_id) { - SCEnter(); - - const PrefilterMpmHttpStartCtx *ctx = pectx; - const MpmCtx *mpm_ctx = ctx->mpm_ctx; - SCLogDebug("running on list %d", ctx->list_id); - - const int list_id = ctx->list_id; - InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); - if (buffer->inspect == NULL) { - uint32_t rawdata_len = 0; - uint8_t *rawdata = GetBufferForTX(txv, idx, det_ctx, - f, flags, &rawdata_len); - if (rawdata_len == 0) - return; - - /* setup buffer and apply transforms */ - InspectionBufferSetup(det_ctx, list_id, buffer, rawdata, rawdata_len); - InspectionBufferApplyTransforms(buffer, ctx->transforms); - } - - const uint32_t data_len = buffer->inspect_len; - const uint8_t *data = buffer->inspect; - - SCLogDebug("mpm'ing buffer:"); - //PrintRawDataFp(stdout, data, data_len); - - if (data != NULL && data_len >= mpm_ctx->minlen) { - (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, - &det_ctx->mtcu, &det_ctx->pmq, data, data_len); - } -} - -static void PrefilterMpmHttpHeaderFree(void *ptr) -{ - SCFree(ptr); -} - -static int PrefilterTxHttpRequestStartRegister(DetectEngineCtx *de_ctx, - SigGroupHead *sgh, MpmCtx *mpm_ctx, - const DetectBufferMpmRegistery *mpm_reg, int list_id) -{ - SCEnter(); - - PrefilterMpmHttpStartCtx *pectx = SCCalloc(1, sizeof(*pectx)); - if (pectx == NULL) - return -1; - pectx->list_id = list_id; - pectx->mpm_ctx = mpm_ctx; - pectx->transforms = &mpm_reg->transforms; - - int r = PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxHttpRequestStart, - mpm_reg->app_v2.alproto, HTP_REQUEST_HEADERS, - pectx, PrefilterMpmHttpHeaderFree, mpm_reg->pname); - if (r != 0) { - SCFree(pectx); - return r; - } - - return r; -} - -/** \brief HTTP Headers Mpm prefilter callback - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * \param f flow to inspect - * \param txv tx to inspect - * \param pectx inspection context - */ -static void PrefilterTxHttpResponseStart(DetectEngineThreadCtx *det_ctx, - const void *pectx, - Packet *p, Flow *f, void *txv, - const uint64_t idx, const uint8_t flags) -{ - SCEnter(); - - const PrefilterMpmHttpStartCtx *ctx = pectx; - const MpmCtx *mpm_ctx = ctx->mpm_ctx; - SCLogDebug("running on list %d", ctx->list_id); - - const int list_id = ctx->list_id; InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); if (buffer->inspect == NULL) { uint32_t rawdata_len = 0; - uint8_t *rawdata = GetBufferForTX(txv, idx, det_ctx, - f, flags, &rawdata_len); + uint8_t *rawdata = GetBufferForTX(txv, det_ctx, f, flow_flags, &rawdata_len); if (rawdata_len == 0) - return; - - /* setup buffer and apply transforms */ - InspectionBufferSetup(det_ctx, list_id, buffer, rawdata, rawdata_len); - InspectionBufferApplyTransforms(buffer, ctx->transforms); - } - - const uint32_t data_len = buffer->inspect_len; - const uint8_t *data = buffer->inspect; - - SCLogDebug("mpm'ing buffer:"); - //PrintRawDataFp(stdout, data, data_len); - - if (data != NULL && data_len >= mpm_ctx->minlen) { - (void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, - &det_ctx->mtcu, &det_ctx->pmq, data, data_len); - } -} - -static int PrefilterTxHttpResponseStartRegister(DetectEngineCtx *de_ctx, - SigGroupHead *sgh, MpmCtx *mpm_ctx, - const DetectBufferMpmRegistery *mpm_reg, int list_id) -{ - SCEnter(); - - PrefilterMpmHttpStartCtx *pectx = SCCalloc(1, sizeof(*pectx)); - if (pectx == NULL) - return -1; - pectx->list_id = list_id; - pectx->mpm_ctx = mpm_ctx; - pectx->transforms = &mpm_reg->transforms; - - int r = PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxHttpResponseStart, - mpm_reg->app_v2.alproto, HTP_RESPONSE_HEADERS, - pectx, PrefilterMpmHttpHeaderFree, mpm_reg->pname); - if (r != 0) { - SCFree(pectx); - return r; - } - - return r; -} - -static int InspectEngineHttpStart( - DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - const DetectEngineAppInspectionEngine *engine, - const Signature *s, - Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id) -{ - const int list_id = engine->sm_list; - InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id); - if (buffer->inspect == NULL) { - SCLogDebug("setting up inspect buffer %d", list_id); - - /* if prefilter didn't already run, we need to consider transformations */ - const DetectEngineTransforms *transforms = NULL; - if (!engine->mpm) { - transforms = engine->v2.transforms; - } + return NULL; - uint32_t rawdata_len = 0; - uint8_t *rawdata = GetBufferForTX(txv, tx_id, det_ctx, - f, flags, &rawdata_len); - if (rawdata_len == 0) { - SCLogDebug("no data"); - goto end; - } - /* setup buffer and apply transforms */ InspectionBufferSetup(det_ctx, list_id, buffer, rawdata, rawdata_len); InspectionBufferApplyTransforms(buffer, transforms); } - const uint32_t data_len = buffer->inspect_len; - const uint8_t *data = buffer->inspect; - const uint64_t offset = buffer->inspect_offset; - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, - NULL, f, (uint8_t *)data, data_len, offset, - DETECT_CI_FLAGS_SINGLE, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - - end: - if (flags & STREAM_TOSERVER) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP1, txv, flags) > - HTP_REQUEST_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } else { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP1, txv, flags) > - HTP_RESPONSE_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; + return buffer; } static int DetectHttpStartSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg) @@ -372,7 +179,7 @@ static int DetectHttpStartSetup(DetectEngineCtx *de_ctx, Signature *s, const cha } /** - * \brief Registers the keyword handlers for the "http_header" keyword. + * \brief Registers the keyword handlers for the "http_start" keyword. */ void DetectHttpStartRegister(void) { @@ -383,15 +190,15 @@ void DetectHttpStartRegister(void) sigmatch_table[DETECT_AL_HTTP_START].Setup = DetectHttpStartSetup; sigmatch_table[DETECT_AL_HTTP_START].flags |= SIGMATCH_NOOPT|SIGMATCH_INFO_STICKY_BUFFER; - DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, - PrefilterTxHttpRequestStartRegister, NULL, ALPROTO_HTTP1, HTP_REQUEST_HEADERS); - DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2, - PrefilterTxHttpResponseStartRegister, NULL, ALPROTO_HTTP1, HTP_RESPONSE_HEADERS); + DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOSERVER, 2, PrefilterGenericMpmRegister, + GetBuffer1ForTX, ALPROTO_HTTP1, HTP_REQUEST_HEADERS); + DetectAppLayerMpmRegister2(BUFFER_NAME, SIG_FLAG_TOCLIENT, 2, PrefilterGenericMpmRegister, + GetBuffer1ForTX, ALPROTO_HTTP1, HTP_RESPONSE_HEADERS); DetectAppLayerInspectEngineRegister2(BUFFER_NAME, ALPROTO_HTTP1, SIG_FLAG_TOSERVER, - HTP_REQUEST_HEADERS, InspectEngineHttpStart, NULL); + HTP_REQUEST_HEADERS, DetectEngineInspectBufferGeneric, GetBuffer1ForTX); DetectAppLayerInspectEngineRegister2(BUFFER_NAME, ALPROTO_HTTP1, SIG_FLAG_TOCLIENT, - HTP_RESPONSE_HEADERS, InspectEngineHttpStart, NULL); + HTP_RESPONSE_HEADERS, DetectEngineInspectBufferGeneric, GetBuffer1ForTX); DetectBufferTypeSetDescriptionByName(BUFFER_NAME, BUFFER_DESC); -- 2.47.3