From e81aa24312a5bcd0b570c1a5d6f764f74ac34acf Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 25 Sep 2023 09:09:07 +0200 Subject: [PATCH 01/18] detect/content-inspect: reduce scope of variables --- src/detect-engine-content-inspection.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/detect-engine-content-inspection.c b/src/detect-engine-content-inspection.c index 0070494380c2..170892044d2a 100644 --- a/src/detect-engine-content-inspection.c +++ b/src/detect-engine-content-inspection.c @@ -133,13 +133,12 @@ int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, DetectEngineT /* search for our pattern, checking the matches recursively. * if we match we look for the next SigMatch as well */ - const uint8_t *found = NULL; - uint32_t offset = 0; - uint32_t depth = buffer_len; uint32_t prev_offset = 0; /**< used in recursive searching */ uint32_t prev_buffer_offset = det_ctx->buffer_offset; do { + uint32_t depth = buffer_len; + uint32_t offset = 0; if ((cd->flags & DETECT_CONTENT_DISTANCE) || (cd->flags & DETECT_CONTENT_WITHIN)) { SCLogDebug("det_ctx->buffer_offset %" PRIu32, det_ctx->buffer_offset); @@ -270,6 +269,7 @@ int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, DetectEngineT #ifdef DEBUG BUG_ON(sbuffer_len > buffer_len); #endif + const uint8_t *found; if (cd->flags & DETECT_CONTENT_ENDS_WITH && depth < buffer_len) { SCLogDebug("depth < buffer_len while DETECT_CONTENT_ENDS_WITH is set. Can't possibly match."); found = NULL; From cc876b5c0d17147a8000529bff9ac0a40bfdd6b4 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 25 Sep 2023 09:09:33 +0200 Subject: [PATCH 02/18] detect/content-inspect: pass const to inspect func --- src/detect-engine-content-inspection.c | 3 ++- src/detect-engine-content-inspection.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/detect-engine-content-inspection.c b/src/detect-engine-content-inspection.c index 170892044d2a..1fa632025017 100644 --- a/src/detect-engine-content-inspection.c +++ b/src/detect-engine-content-inspection.c @@ -97,7 +97,8 @@ */ int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, - uint32_t buffer_len, uint32_t stream_start_offset, uint8_t flags, uint8_t inspection_mode) + const uint32_t buffer_len, const uint32_t stream_start_offset, const uint8_t flags, + const uint8_t inspection_mode) { SCEnter(); KEYWORD_PROFILING_START; diff --git a/src/detect-engine-content-inspection.h b/src/detect-engine-content-inspection.h index 188ebef2d881..1d04a48b1855 100644 --- a/src/detect-engine-content-inspection.h +++ b/src/detect-engine-content-inspection.h @@ -54,7 +54,8 @@ int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, DetectEngineT /* implicit "public" just returns true match, false no match */ bool DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, - uint32_t buffer_len, uint32_t stream_start_offset, uint8_t flags, uint8_t inspection_mode); + const uint32_t buffer_len, const uint32_t stream_start_offset, const uint8_t flags, + const uint8_t inspection_mode); void DetectEngineContentInspectionRegisterTests(void); From fae1af6d7692f0e3a64316a15c7db184734c8c55 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sat, 23 Sep 2023 09:26:12 +0200 Subject: [PATCH 03/18] detect/content-inspect: remove const casting --- src/detect-dns-query.c | 2 +- src/detect-engine-frame.c | 9 ++------- src/detect-engine-payload.c | 4 ++-- src/detect-engine.c | 5 ++--- src/detect-file-data.c | 2 +- src/detect-filemagic.c | 2 +- src/detect-filename.c | 2 +- src/detect-http-client-body.c | 5 ++--- src/detect-http-header.c | 2 +- src/detect-http2.c | 2 +- src/detect-ike-vendor.c | 2 +- src/detect-krb5-cname.c | 2 +- src/detect-krb5-sname.c | 2 +- src/detect-mqtt-subscribe-topic.c | 2 +- src/detect-mqtt-unsubscribe-topic.c | 2 +- src/detect-quic-cyu-hash.c | 2 +- src/detect-quic-cyu-string.c | 2 +- src/detect-template-rust-buffer.c | 2 +- src/detect-tls-certs.c | 2 +- 19 files changed, 23 insertions(+), 30 deletions(-) diff --git a/src/detect-dns-query.c b/src/detect-dns-query.c index d2dbe8e99021..a0bf46f3867d 100644 --- a/src/detect-dns-query.c +++ b/src/detect-dns-query.c @@ -115,7 +115,7 @@ static uint8_t DetectEngineInspectDnsQuery(DetectEngineCtx *de_ctx, DetectEngine break; const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, + buffer->inspect, buffer->inspect_len, buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; diff --git a/src/detect-engine-frame.c b/src/detect-engine-frame.c index 0ed70757d599..71ac9d3d1674 100644 --- a/src/detect-engine-frame.c +++ b/src/detect-engine-frame.c @@ -306,13 +306,8 @@ static int DetectFrameInspectUdp(DetectEngineThreadCtx *det_ctx, if (buffer->inspect == NULL) return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; - const uint32_t data_len = buffer->inspect_len; - const uint8_t *data = buffer->inspect; - - // PrintRawDataFp(stdout, data, data_len); - const bool match = DetectEngineContentInspection(det_ctx->de_ctx, det_ctx, s, engine->smd, p, - p->flow, (uint8_t *)data, data_len, 0, buffer->flags, + p->flow, buffer->inspect, buffer->inspect_len, 0, buffer->flags, DETECT_ENGINE_CONTENT_INSPECTION_MODE_FRAME); if (match) { SCLogDebug("match!"); @@ -479,7 +474,7 @@ static int FrameStreamDataInspectFunc( BUG_ON(fsd->frame->len > 0 && (int64_t)data_len > fsd->frame->len); const bool match = DetectEngineContentInspection(det_ctx->de_ctx, det_ctx, s, engine->smd, p, - p->flow, (uint8_t *)data, data_len, data_offset, buffer->flags, + p->flow, data, data_len, data_offset, buffer->flags, DETECT_ENGINE_CONTENT_INSPECTION_MODE_FRAME); if (match) { SCLogDebug("DETECT_ENGINE_INSPECT_SIG_MATCH"); diff --git a/src/detect-engine-payload.c b/src/detect-engine-payload.c index 7da3c3b81f93..d051303ddbb1 100644 --- a/src/detect-engine-payload.c +++ b/src/detect-engine-payload.c @@ -227,7 +227,7 @@ static int StreamContentInspectFunc( #endif const bool match = DetectEngineContentInspection(smd->de_ctx, smd->det_ctx, smd->s, - smd->s->sm_arrays[DETECT_SM_LIST_PMATCH], NULL, smd->f, (uint8_t *)data, data_len, 0, + smd->s->sm_arrays[DETECT_SM_LIST_PMATCH], NULL, smd->f, data, data_len, 0, 0, // TODO DETECT_ENGINE_CONTENT_INSPECTION_MODE_STREAM); if (match) { @@ -282,7 +282,7 @@ static int StreamContentInspectEngineFunc( #endif const bool match = DetectEngineContentInspection(smd->de_ctx, smd->det_ctx, smd->s, smd->smd, - NULL, smd->f, (uint8_t *)data, data_len, 0, 0, // TODO + NULL, smd->f, data, data_len, 0, 0, // TODO DETECT_ENGINE_CONTENT_INSPECTION_MODE_STREAM); if (match) { SCReturnInt(1); diff --git a/src/detect-engine.c b/src/detect-engine.c index a4ce2126544d..58aee1bfc078 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -2206,9 +2206,8 @@ uint8_t DetectEngineInspectBufferGeneric(DetectEngineCtx *de_ctx, DetectEngineTh /* Inspect all the uricontents fetched on each * transaction at the app layer */ - const bool match = - DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, (uint8_t *)data, - data_len, offset, ci_flags, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); + const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, data, + data_len, offset, ci_flags, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; } else { diff --git a/src/detect-file-data.c b/src/detect-file-data.c index f31715adda01..533fc8441d93 100644 --- a/src/detect-file-data.c +++ b/src/detect-file-data.c @@ -415,7 +415,7 @@ uint8_t DetectEngineInspectFiledata(DetectEngineCtx *de_ctx, DetectEngineThreadC ciflags |= DETECT_CI_FLAGS_START; const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, ciflags, + buffer->inspect, buffer->inspect_len, buffer->inspect_offset, ciflags, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; diff --git a/src/detect-filemagic.c b/src/detect-filemagic.c index 7ade159fb52d..b7a737e6c7b7 100644 --- a/src/detect-filemagic.c +++ b/src/detect-filemagic.c @@ -321,7 +321,7 @@ static uint8_t DetectEngineInspectFilemagic(DetectEngineCtx *de_ctx, DetectEngin continue; const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, + buffer->inspect, buffer->inspect_len, buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; diff --git a/src/detect-filename.c b/src/detect-filename.c index 88e580862452..10646f019f1a 100644 --- a/src/detect-filename.c +++ b/src/detect-filename.c @@ -258,7 +258,7 @@ static uint8_t DetectEngineInspectFilename(DetectEngineCtx *de_ctx, DetectEngine continue; const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, + buffer->inspect, buffer->inspect_len, buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; diff --git a/src/detect-http-client-body.c b/src/detect-http-client-body.c index 1d3d7a87cc88..9e14b1b49fad 100644 --- a/src/detect-http-client-body.c +++ b/src/detect-http-client-body.c @@ -325,9 +325,8 @@ static uint8_t DetectEngineInspectBufferHttpBody(DetectEngineCtx *de_ctx, /* Inspect all the uricontents fetched on each * transaction at the app layer */ - const bool match = - DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, (uint8_t *)data, - data_len, offset, ci_flags, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); + const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, data, + data_len, offset, ci_flags, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; } diff --git a/src/detect-http-header.c b/src/detect-http-header.c index a4596c4085f2..91e17d886379 100644 --- a/src/detect-http-header.c +++ b/src/detect-http-header.c @@ -545,7 +545,7 @@ static uint8_t DetectEngineInspectHttp2Header(DetectEngineCtx *de_ctx, break; const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, + buffer->inspect, buffer->inspect_len, buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; diff --git a/src/detect-http2.c b/src/detect-http2.c index a1ede963825e..a65115a14cea 100644 --- a/src/detect-http2.c +++ b/src/detect-http2.c @@ -703,7 +703,7 @@ static uint8_t DetectEngineInspectHttp2HeaderName(DetectEngineCtx *de_ctx, break; const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, + buffer->inspect, buffer->inspect_len, buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; diff --git a/src/detect-ike-vendor.c b/src/detect-ike-vendor.c index f5c5b94f35d5..3b84da26660b 100644 --- a/src/detect-ike-vendor.c +++ b/src/detect-ike-vendor.c @@ -156,7 +156,7 @@ static uint8_t DetectEngineInspectIkeVendor(DetectEngineCtx *de_ctx, DetectEngin break; const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, + buffer->inspect, buffer->inspect_len, buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; diff --git a/src/detect-krb5-cname.c b/src/detect-krb5-cname.c index 8664f2bc2877..d509116ee73b 100644 --- a/src/detect-krb5-cname.c +++ b/src/detect-krb5-cname.c @@ -104,7 +104,7 @@ static uint8_t DetectEngineInspectKrb5CName(DetectEngineCtx *de_ctx, DetectEngin break; const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, + buffer->inspect, buffer->inspect_len, buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; diff --git a/src/detect-krb5-sname.c b/src/detect-krb5-sname.c index 1e4ae24a4bd1..9fbe550b02f9 100644 --- a/src/detect-krb5-sname.c +++ b/src/detect-krb5-sname.c @@ -105,7 +105,7 @@ static uint8_t DetectEngineInspectKrb5SName(DetectEngineCtx *de_ctx, DetectEngin break; const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, + buffer->inspect, buffer->inspect_len, buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; diff --git a/src/detect-mqtt-subscribe-topic.c b/src/detect-mqtt-subscribe-topic.c index 9eaf39d3029c..9e0058785ec1 100644 --- a/src/detect-mqtt-subscribe-topic.c +++ b/src/detect-mqtt-subscribe-topic.c @@ -108,7 +108,7 @@ static uint8_t DetectEngineInspectMQTTSubscribeTopic(DetectEngineCtx *de_ctx, break; const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, + buffer->inspect, buffer->inspect_len, buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; diff --git a/src/detect-mqtt-unsubscribe-topic.c b/src/detect-mqtt-unsubscribe-topic.c index 268d72bc8789..297142dd83da 100644 --- a/src/detect-mqtt-unsubscribe-topic.c +++ b/src/detect-mqtt-unsubscribe-topic.c @@ -108,7 +108,7 @@ static uint8_t DetectEngineInspectMQTTUnsubscribeTopic(DetectEngineCtx *de_ctx, break; const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, + buffer->inspect, buffer->inspect_len, buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; diff --git a/src/detect-quic-cyu-hash.c b/src/detect-quic-cyu-hash.c index 88197a5e382a..246f36a41efe 100644 --- a/src/detect-quic-cyu-hash.c +++ b/src/detect-quic-cyu-hash.c @@ -107,7 +107,7 @@ static uint8_t DetectEngineInspectQuicHash(DetectEngineCtx *de_ctx, DetectEngine break; const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, + buffer->inspect, buffer->inspect_len, buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; diff --git a/src/detect-quic-cyu-string.c b/src/detect-quic-cyu-string.c index 9290fa41233c..dfec432c2049 100644 --- a/src/detect-quic-cyu-string.c +++ b/src/detect-quic-cyu-string.c @@ -105,7 +105,7 @@ static uint8_t DetectEngineInspectQuicString(DetectEngineCtx *de_ctx, break; const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, + buffer->inspect, buffer->inspect_len, buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; diff --git a/src/detect-template-rust-buffer.c b/src/detect-template-rust-buffer.c index f1c8c97bb278..3f016f4b164b 100644 --- a/src/detect-template-rust-buffer.c +++ b/src/detect-template-rust-buffer.c @@ -103,7 +103,7 @@ static uint8_t DetectEngineInspectTemplateRustBuffer(DetectEngineCtx *de_ctx, if (data != NULL) { const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)data, data_len, 0, DETECT_CI_FLAGS_SINGLE, + data, data_len, 0, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { ret = DETECT_ENGINE_INSPECT_SIG_MATCH; diff --git a/src/detect-tls-certs.c b/src/detect-tls-certs.c index 9ff185c494d6..7310461ea235 100644 --- a/src/detect-tls-certs.c +++ b/src/detect-tls-certs.c @@ -195,7 +195,7 @@ static uint8_t DetectEngineInspectTlsCerts(DetectEngineCtx *de_ctx, DetectEngine break; const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - (uint8_t *)buffer->inspect, buffer->inspect_len, buffer->inspect_offset, + buffer->inspect, buffer->inspect_len, buffer->inspect_offset, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; From ea330288a83e4e3e9cbda7d115b68577af7851e2 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sat, 23 Sep 2023 09:32:14 +0200 Subject: [PATCH 04/18] detect/content-inspect: assist branch prediction Hitting the recursion limit should be rare. --- src/detect-engine-content-inspection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detect-engine-content-inspection.c b/src/detect-engine-content-inspection.c index 1fa632025017..6c13b443488d 100644 --- a/src/detect-engine-content-inspection.c +++ b/src/detect-engine-content-inspection.c @@ -105,7 +105,7 @@ int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, DetectEngineT det_ctx->inspection_recursion_counter++; - if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) { + if (unlikely(det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit)) { KEYWORD_PROFILING_END(det_ctx, smd->type, 0); SCReturnInt(-1); } From b1d35b315f4f4e29f7a52122128f4c582e8ef06b Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sat, 2 Dec 2023 09:41:02 +0100 Subject: [PATCH 05/18] detect/content-inspect: switch type of enum --- src/detect-engine-content-inspection.c | 4 ++-- src/detect-engine-content-inspection.h | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/detect-engine-content-inspection.c b/src/detect-engine-content-inspection.c index 6c13b443488d..d5ffc135af67 100644 --- a/src/detect-engine-content-inspection.c +++ b/src/detect-engine-content-inspection.c @@ -98,7 +98,7 @@ int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, const uint32_t buffer_len, const uint32_t stream_start_offset, const uint8_t flags, - const uint8_t inspection_mode) + const enum DetectContentInspectionType inspection_mode) { SCEnter(); KEYWORD_PROFILING_START; @@ -701,7 +701,7 @@ int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, DetectEngineT bool DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, const uint32_t buffer_len, const uint32_t stream_start_offset, const uint8_t flags, - const uint8_t inspection_mode) + const enum DetectContentInspectionType inspection_mode) { det_ctx->buffer_offset = 0; det_ctx->inspection_recursion_counter = 0; diff --git a/src/detect-engine-content-inspection.h b/src/detect-engine-content-inspection.h index 1d04a48b1855..06c5407f5a67 100644 --- a/src/detect-engine-content-inspection.h +++ b/src/detect-engine-content-inspection.h @@ -28,7 +28,7 @@ /** indication to content engine what type of data * we're inspecting */ -enum { +enum DetectContentInspectionType { DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD = 0, /* enables 'replace' logic */ DETECT_ENGINE_CONTENT_INSPECTION_MODE_HEADER, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STREAM, @@ -50,12 +50,13 @@ enum { int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, const uint32_t buffer_len, const uint32_t stream_start_offset, const uint8_t flags, - const uint8_t inspection_mode); + const enum DetectContentInspectionType inspection_mode); + /* implicit "public" just returns true match, false no match */ bool DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, const uint32_t buffer_len, const uint32_t stream_start_offset, const uint8_t flags, - const uint8_t inspection_mode); + const enum DetectContentInspectionType inspection_mode); void DetectEngineContentInspectionRegisterTests(void); From 11a930c37443bcd2d633992ba300aad27e519f09 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sat, 2 Dec 2023 09:44:06 +0100 Subject: [PATCH 06/18] detect/content-inspect: add entry for InspectionBuffer --- src/detect-engine-content-inspection.c | 19 +++++++++++++++++++ src/detect-engine-content-inspection.h | 5 +++++ 2 files changed, 24 insertions(+) diff --git a/src/detect-engine-content-inspection.c b/src/detect-engine-content-inspection.c index d5ffc135af67..09d838378fea 100644 --- a/src/detect-engine-content-inspection.c +++ b/src/detect-engine-content-inspection.c @@ -714,6 +714,25 @@ bool DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCt return false; } +/** \brief wrapper around DetectEngineContentInspectionInternal to return true/false only + * + * \param smd sigmatches to evaluate + */ +bool DetectEngineContentInspectionBuffer(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, + const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const InspectionBuffer *b, + const enum DetectContentInspectionType inspection_mode) +{ + det_ctx->buffer_offset = 0; + det_ctx->inspection_recursion_counter = 0; + + int r = DetectEngineContentInspectionInternal(de_ctx, det_ctx, s, smd, p, f, b->inspect, + b->inspect_len, b->inspect_offset, b->flags, inspection_mode); + if (r == 1) + return true; + else + return false; +} + #ifdef UNITTESTS #include "tests/detect-engine-content-inspection.c" #endif diff --git a/src/detect-engine-content-inspection.h b/src/detect-engine-content-inspection.h index 06c5407f5a67..e4913a65a1e9 100644 --- a/src/detect-engine-content-inspection.h +++ b/src/detect-engine-content-inspection.h @@ -58,6 +58,11 @@ bool DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCt const uint32_t buffer_len, const uint32_t stream_start_offset, const uint8_t flags, const enum DetectContentInspectionType inspection_mode); +/* entry for inspection buffers */ +bool DetectEngineContentInspectionBuffer(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, + const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const InspectionBuffer *b, + const enum DetectContentInspectionType inspection_mode); + void DetectEngineContentInspectionRegisterTests(void); #endif /* __DETECT_ENGINE_CONTENT_INSPECTION_H__ */ From c1e10abf8e22c315d252fcb60f0e41eb664117c9 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sat, 2 Dec 2023 09:44:58 +0100 Subject: [PATCH 07/18] detect/dns.query: use new content inspect entry --- src/detect-dns-query.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/detect-dns-query.c b/src/detect-dns-query.c index a0bf46f3867d..43e1595e491a 100644 --- a/src/detect-dns-query.c +++ b/src/detect-dns-query.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2013-2018 Open Information Security Foundation +/* Copyright (C) 2013-2023 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 @@ -92,6 +92,7 @@ static InspectionBuffer *DnsQueryGetData(DetectEngineThreadCtx *det_ctx, return NULL; } InspectionBufferSetupMulti(buffer, transforms, data, data_len); + buffer->flags = DETECT_CI_FLAGS_SINGLE; SCReturnPtr(buffer, "InspectionBuffer"); } @@ -114,9 +115,8 @@ static uint8_t DetectEngineInspectDnsQuery(DetectEngineCtx *de_ctx, DetectEngine if (buffer == NULL || buffer->inspect == NULL) break; - const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - buffer->inspect, buffer->inspect_len, buffer->inspect_offset, - DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); + const bool match = DetectEngineContentInspectionBuffer(de_ctx, det_ctx, s, engine->smd, + NULL, f, buffer, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; } From c5dbb3cb30ccc51407b2668f9370501a86fdaf16 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sat, 2 Dec 2023 09:45:15 +0100 Subject: [PATCH 08/18] detect/krb5.sname: use new content inspect entry --- src/detect-krb5-sname.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/detect-krb5-sname.c b/src/detect-krb5-sname.c index 9fbe550b02f9..dae5c46e5215 100644 --- a/src/detect-krb5-sname.c +++ b/src/detect-krb5-sname.c @@ -81,6 +81,7 @@ static InspectionBuffer *GetKrb5SNameData(DetectEngineThreadCtx *det_ctx, } InspectionBufferSetupMulti(buffer, transforms, b, b_len); + buffer->flags = DETECT_CI_FLAGS_SINGLE; SCReturnPtr(buffer, "InspectionBuffer"); } @@ -100,13 +101,11 @@ static uint8_t DetectEngineInspectKrb5SName(DetectEngineCtx *de_ctx, DetectEngin struct Krb5PrincipalNameDataArgs cbdata = { local_id, txv, }; InspectionBuffer *buffer = GetKrb5SNameData(det_ctx, transforms, f, &cbdata, engine->sm_list); - if (buffer == NULL || buffer->inspect == NULL) break; - const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, engine->smd, NULL, f, - buffer->inspect, buffer->inspect_len, buffer->inspect_offset, - DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); + const bool match = DetectEngineContentInspectionBuffer(de_ctx, det_ctx, s, engine->smd, + NULL, f, buffer, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); if (match) { return DETECT_ENGINE_INSPECT_SIG_MATCH; } From 68a3d0abae8e0e9d9f1df7188bae16fc7ec68dcc Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sat, 23 Sep 2023 13:01:05 +0200 Subject: [PATCH 09/18] detect/base64: move content inspection logic Integrate with rest of content inspect code. --- src/detect-base64-data.c | 13 ------------- src/detect-base64-data.h | 2 -- src/detect-engine-content-inspection.c | 14 ++++++++++---- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/detect-base64-data.c b/src/detect-base64-data.c index 09d89113d675..770061350a86 100644 --- a/src/detect-base64-data.c +++ b/src/detect-base64-data.c @@ -61,19 +61,6 @@ static int DetectBase64DataSetup(DetectEngineCtx *de_ctx, Signature *s, return 0; } -int DetectBase64DataDoMatch(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, const Signature *s, Flow *f) -{ - if (det_ctx->base64_decoded_len) { - return DetectEngineContentInspectionInternal(de_ctx, det_ctx, s, - s->sm_arrays[DETECT_SM_LIST_BASE64_DATA], NULL, f, det_ctx->base64_decoded, - det_ctx->base64_decoded_len, 0, DETECT_CI_FLAGS_SINGLE, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); - } - - return 0; -} - #ifdef UNITTESTS static int g_file_data_buffer_id = 0; diff --git a/src/detect-base64-data.h b/src/detect-base64-data.h index 38bb93fc0691..4b7d54d04ebe 100644 --- a/src/detect-base64-data.h +++ b/src/detect-base64-data.h @@ -19,7 +19,5 @@ #define __DETECT_BASE64_DATA_H__ void DetectBase64DataRegister(void); -int DetectBase64DataDoMatch(DetectEngineCtx *, DetectEngineThreadCtx *, - const Signature *, Flow *); #endif /* __DETECT_BASE64_DATA_H__ */ diff --git a/src/detect-engine-content-inspection.c b/src/detect-engine-content-inspection.c index 09d838378fea..19e7fe1096f9 100644 --- a/src/detect-engine-content-inspection.c +++ b/src/detect-engine-content-inspection.c @@ -651,10 +651,16 @@ int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, DetectEngineT } else if (smd->type == DETECT_BASE64_DECODE) { if (DetectBase64DecodeDoMatch(det_ctx, s, smd, buffer, buffer_len)) { if (s->sm_arrays[DETECT_SM_LIST_BASE64_DATA] != NULL) { - KEYWORD_PROFILING_END(det_ctx, smd->type, 1); - if (DetectBase64DataDoMatch(de_ctx, det_ctx, s, f) == 1) { - /* Base64 is a terminal list. */ - goto final_match; + if (det_ctx->base64_decoded_len) { + KEYWORD_PROFILING_END(det_ctx, smd->type, 1); + int r = DetectEngineContentInspectionInternal(de_ctx, det_ctx, s, + s->sm_arrays[DETECT_SM_LIST_BASE64_DATA], NULL, f, + det_ctx->base64_decoded, det_ctx->base64_decoded_len, 0, + DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); + if (r == 1) { + /* Base64 is a terminal list. */ + goto final_match; + } } } } From 8078a733ecc00534412af7d40aab8a848ae81175 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sun, 24 Sep 2023 06:56:57 +0200 Subject: [PATCH 10/18] detect/content-inspect: reduce scope of internal func --- src/detect-engine-content-inspection.c | 7 ++++--- src/detect-engine-content-inspection.h | 6 ------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/detect-engine-content-inspection.c b/src/detect-engine-content-inspection.c index 19e7fe1096f9..3a3b786e4670 100644 --- a/src/detect-engine-content-inspection.c +++ b/src/detect-engine-content-inspection.c @@ -95,9 +95,10 @@ * \retval 0 no match * \retval 1 match */ -int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, - const uint32_t buffer_len, const uint32_t stream_start_offset, const uint8_t flags, +static int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, + DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, + Flow *f, const uint8_t *buffer, const uint32_t buffer_len, + const uint32_t stream_start_offset, const uint8_t flags, const enum DetectContentInspectionType inspection_mode) { SCEnter(); diff --git a/src/detect-engine-content-inspection.h b/src/detect-engine-content-inspection.h index e4913a65a1e9..842c32e63ac3 100644 --- a/src/detect-engine-content-inspection.h +++ b/src/detect-engine-content-inspection.h @@ -46,12 +46,6 @@ enum DetectContentInspectionType { * inspection function contains both start and end of the data. */ #define DETECT_CI_FLAGS_SINGLE (DETECT_CI_FLAGS_START|DETECT_CI_FLAGS_END) -/* "internal" returns 1 match, 0 no match, -1 can't match */ -int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, - const uint32_t buffer_len, const uint32_t stream_start_offset, const uint8_t flags, - const enum DetectContentInspectionType inspection_mode); - /* implicit "public" just returns true match, false no match */ bool DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, From a2428cfad7c420adb33445f735afe3fd9789b566 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sun, 24 Sep 2023 06:51:33 +0200 Subject: [PATCH 11/18] detect/content-inspect: localize recursion counting Use stack local var instead of DetectEngineThreadCtx member. Make sure the limit is a const so we can avoid rereading it. --- src/detect-engine-content-inspection.c | 51 +++++++++++++------- src/detect-tls-sni.c | 2 +- src/detect.h | 3 -- src/tests/detect-engine-content-inspection.c | 43 +++++++++-------- 4 files changed, 57 insertions(+), 42 deletions(-) diff --git a/src/detect-engine-content-inspection.c b/src/detect-engine-content-inspection.c index 3a3b786e4670..868a26d3ce12 100644 --- a/src/detect-engine-content-inspection.c +++ b/src/detect-engine-content-inspection.c @@ -66,6 +66,17 @@ #include "util-lua.h" #endif +#ifdef UNITTESTS +thread_local uint32_t ut_inspection_recursion_counter = 0; +#endif + +struct DetectEngineContentInspectionCtx { + struct { + uint32_t count; + const uint32_t limit; + } recursion; +}; + /** * \brief Run the actual payload match functions * @@ -74,7 +85,6 @@ * For accounting the last match in relative matching the * det_ctx->buffer_offset int is used. * - * \param de_ctx Detection engine context * \param det_ctx Detection engine thread context * \param s Signature to inspect * \param sm SigMatch to inspect @@ -95,18 +105,17 @@ * \retval 0 no match * \retval 1 match */ -static int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, - Flow *f, const uint8_t *buffer, const uint32_t buffer_len, +static int DetectEngineContentInspectionInternal(DetectEngineThreadCtx *det_ctx, + struct DetectEngineContentInspectionCtx *ctx, const Signature *s, const SigMatchData *smd, + Packet *p, Flow *f, const uint8_t *buffer, const uint32_t buffer_len, const uint32_t stream_start_offset, const uint8_t flags, const enum DetectContentInspectionType inspection_mode) { SCEnter(); KEYWORD_PROFILING_START; - det_ctx->inspection_recursion_counter++; - - if (unlikely(det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit)) { + ctx->recursion.count++; + if (unlikely(ctx->recursion.count == ctx->recursion.limit)) { KEYWORD_PROFILING_END(det_ctx, smd->type, 0); SCReturnInt(-1); } @@ -349,9 +358,8 @@ static int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, /* see if the next buffer keywords match. If not, we will * search for another occurrence of this content and see * if the others match then until we run out of matches */ - int r = DetectEngineContentInspectionInternal(de_ctx, det_ctx, s, smd + 1, - p, f, buffer, buffer_len, stream_start_offset, flags, - inspection_mode); + int r = DetectEngineContentInspectionInternal(det_ctx, ctx, s, smd + 1, p, + f, buffer, buffer_len, stream_start_offset, flags, inspection_mode); if (r == 1) { SCReturnInt(1); } else if (r == -1) { @@ -448,7 +456,7 @@ static int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, /* see if the next payload keywords match. If not, we will * search for another occurrence of this pcre and see * if the others match, until we run out of matches */ - r = DetectEngineContentInspectionInternal(de_ctx, det_ctx, s, smd + 1, p, f, buffer, + r = DetectEngineContentInspectionInternal(det_ctx, ctx, s, smd + 1, p, f, buffer, buffer_len, stream_start_offset, flags, inspection_mode); if (r == 1) { SCReturnInt(1); @@ -654,7 +662,7 @@ static int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, if (s->sm_arrays[DETECT_SM_LIST_BASE64_DATA] != NULL) { if (det_ctx->base64_decoded_len) { KEYWORD_PROFILING_END(det_ctx, smd->type, 1); - int r = DetectEngineContentInspectionInternal(de_ctx, det_ctx, s, + int r = DetectEngineContentInspectionInternal(det_ctx, ctx, s, s->sm_arrays[DETECT_SM_LIST_BASE64_DATA], NULL, f, det_ctx->base64_decoded, det_ctx->base64_decoded_len, 0, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE); @@ -692,7 +700,7 @@ static int DetectEngineContentInspectionInternal(DetectEngineCtx *de_ctx, * the buffer portion of the signature matched. */ if (!smd->is_last) { KEYWORD_PROFILING_END(det_ctx, smd->type, 1); - int r = DetectEngineContentInspectionInternal(de_ctx, det_ctx, s, smd + 1, p, f, buffer, + int r = DetectEngineContentInspectionInternal(det_ctx, ctx, s, smd + 1, p, f, buffer, buffer_len, stream_start_offset, flags, inspection_mode); SCReturnInt(r); } @@ -710,11 +718,15 @@ bool DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCt const uint32_t buffer_len, const uint32_t stream_start_offset, const uint8_t flags, const enum DetectContentInspectionType inspection_mode) { + struct DetectEngineContentInspectionCtx ctx = { .recursion.count = 0, + .recursion.limit = de_ctx->inspection_recursion_limit }; det_ctx->buffer_offset = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspectionInternal(de_ctx, det_ctx, s, smd, p, f, buffer, buffer_len, + int r = DetectEngineContentInspectionInternal(det_ctx, &ctx, s, smd, p, f, buffer, buffer_len, stream_start_offset, flags, inspection_mode); +#ifdef UNITTESTS + ut_inspection_recursion_counter = ctx.recursion.count; +#endif if (r == 1) return true; else @@ -729,11 +741,16 @@ bool DetectEngineContentInspectionBuffer(DetectEngineCtx *de_ctx, DetectEngineTh const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const InspectionBuffer *b, const enum DetectContentInspectionType inspection_mode) { + struct DetectEngineContentInspectionCtx ctx = { .recursion.count = 0, + .recursion.limit = de_ctx->inspection_recursion_limit }; + det_ctx->buffer_offset = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspectionInternal(de_ctx, det_ctx, s, smd, p, f, b->inspect, + int r = DetectEngineContentInspectionInternal(det_ctx, &ctx, s, smd, p, f, b->inspect, b->inspect_len, b->inspect_offset, b->flags, inspection_mode); +#ifdef UNITTESTS + ut_inspection_recursion_counter = ctx.recursion.count; +#endif if (r == 1) return true; else diff --git a/src/detect-tls-sni.c b/src/detect-tls-sni.c index 69b066e8e979..6ac644f1de3a 100644 --- a/src/detect-tls-sni.c +++ b/src/detect-tls-sni.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2016 Open Information Security Foundation +/* Copyright (C) 2007-2023 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 diff --git a/src/detect.h b/src/detect.h index 3861b603d801..9230f501d697 100644 --- a/src/detect.h +++ b/src/detect.h @@ -1159,9 +1159,6 @@ typedef struct DetectEngineThreadCtx_ { SC_ATOMIC_DECLARE(int, so_far_used_by_detect); - /* holds the current recursion depth on content inspection */ - int inspection_recursion_counter; - /** array of signature pointers we're going to inspect in the detection * loop. */ Signature **match_array; diff --git a/src/tests/detect-engine-content-inspection.c b/src/tests/detect-engine-content-inspection.c index ee1b605f2c0d..65a4f578b824 100644 --- a/src/tests/detect-engine-content-inspection.c +++ b/src/tests/detect-engine-content-inspection.c @@ -29,33 +29,34 @@ #include "../detect.h" #include "detect-engine-build.h" +extern thread_local uint32_t ut_inspection_recursion_counter; + #define TEST_HEADER \ ThreadVars tv; \ memset(&tv, 0, sizeof(tv)); \ Flow f; \ memset(&f, 0, sizeof(f)); -#define TEST_RUN(buf, buflen, sig, match, steps) \ -{ \ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); \ - FAIL_IF_NULL(de_ctx); \ - DetectEngineThreadCtx *det_ctx = NULL; \ - char rule[2048]; \ - snprintf(rule, sizeof(rule), "alert tcp any any -> any any (%s sid:1; rev:1;)", (sig)); \ - Signature *s = DetectEngineAppendSig(de_ctx, rule); \ - FAIL_IF_NULL(s); \ - SigGroupBuild(de_ctx); \ - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); \ - FAIL_IF_NULL(det_ctx); \ - int r = DetectEngineContentInspection(de_ctx, det_ctx, \ - s, s->sm_arrays[DETECT_SM_LIST_PMATCH], NULL, &f, \ - (uint8_t *)(buf), (buflen), 0, DETECT_CI_FLAGS_SINGLE, \ - DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD); \ - FAIL_IF_NOT(r == (match)); \ - FAIL_IF_NOT(det_ctx->inspection_recursion_counter == (steps)); \ - DetectEngineThreadCtxDeinit(&tv, det_ctx); \ - DetectEngineCtxFree(de_ctx); \ -} +#define TEST_RUN(buf, buflen, sig, match, steps) \ + { \ + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); \ + FAIL_IF_NULL(de_ctx); \ + DetectEngineThreadCtx *det_ctx = NULL; \ + char rule[2048]; \ + snprintf(rule, sizeof(rule), "alert tcp any any -> any any (%s sid:1; rev:1;)", (sig)); \ + Signature *s = DetectEngineAppendSig(de_ctx, rule); \ + FAIL_IF_NULL(s); \ + SigGroupBuild(de_ctx); \ + DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); \ + FAIL_IF_NULL(det_ctx); \ + int r = DetectEngineContentInspection(de_ctx, det_ctx, s, \ + s->sm_arrays[DETECT_SM_LIST_PMATCH], NULL, &f, (uint8_t *)(buf), (buflen), 0, \ + DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD); \ + FAIL_IF_NOT(r == (match)); \ + FAIL_IF_NOT(ut_inspection_recursion_counter == (steps)); \ + DetectEngineThreadCtxDeinit(&tv, det_ctx); \ + DetectEngineCtxFree(de_ctx); \ + } #define TEST_FOOTER \ PASS From 890eb712ef50c9b62c727b75702142486d42bad6 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sun, 24 Sep 2023 07:42:37 +0200 Subject: [PATCH 12/18] detect/content-inspect: flatten branches Flatten else branches after terminating ifs. --- src/detect-engine-content-inspection.c | 138 ++++++++++++------------- 1 file changed, 68 insertions(+), 70 deletions(-) diff --git a/src/detect-engine-content-inspection.c b/src/detect-engine-content-inspection.c index 868a26d3ce12..ac8a39226ab9 100644 --- a/src/detect-engine-content-inspection.c +++ b/src/detect-engine-content-inspection.c @@ -307,83 +307,81 @@ static int DetectEngineContentInspectionInternal(DetectEngineThreadCtx *det_ctx, } else { goto match; } - } else { - uint32_t match_offset = (uint32_t)((found - buffer) + cd->content_len); - if (cd->flags & DETECT_CONTENT_NEGATED) { - SCLogDebug("content %" PRIu32 " matched at offset %" PRIu32 - ", but negated so no match", - cd->id, match_offset); - /* don't bother carrying recursive matches now, for preceding - * relative keywords */ - - /* found a match but not at the end of the buffer */ - if (cd->flags & DETECT_CONTENT_ENDS_WITH) { - if (sbuffer_len != match_offset) { - SCLogDebug("content \"%s\" %" PRIu32 " matched at offset %" PRIu32 - ", but not at end of buffer so match", - cd->content, cd->id, match_offset); - goto match; - } - } - if (DETECT_CONTENT_IS_SINGLE(cd)) { - goto no_match_discontinue; + } + + uint32_t match_offset = (uint32_t)((found - buffer) + cd->content_len); + if (cd->flags & DETECT_CONTENT_NEGATED) { + SCLogDebug("content %" PRIu32 " matched at offset %" PRIu32 + ", but negated so no match", + cd->id, match_offset); + /* don't bother carrying recursive matches now, for preceding + * relative keywords */ + + /* found a match but not at the end of the buffer */ + if (cd->flags & DETECT_CONTENT_ENDS_WITH) { + if (sbuffer_len != match_offset) { + SCLogDebug("content \"%s\" %" PRIu32 " matched at offset %" PRIu32 + ", but not at end of buffer so match", + cd->content, cd->id, match_offset); + goto match; } - goto no_match; - } else { - SCLogDebug("content %" PRIu32 " matched at offset %" PRIu32 "", cd->id, - match_offset); - det_ctx->buffer_offset = match_offset; - - if ((cd->flags & DETECT_CONTENT_ENDS_WITH) == 0 || match_offset == buffer_len) { - /* Match branch, add replace to the list if needed */ - if (cd->flags & DETECT_CONTENT_REPLACE) { - if (inspection_mode == DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD) { - /* we will need to replace content if match is confirmed - * cast to non-const as replace writes to it. */ - det_ctx->replist = DetectReplaceAddToList( - det_ctx->replist, (uint8_t *)found, cd); - } else { - SCLogWarning("Can't modify payload without packet"); - } - } + } + if (DETECT_CONTENT_IS_SINGLE(cd)) { + goto no_match_discontinue; + } + goto no_match; + } - /* if this is the last match we're done */ - if (smd->is_last) { - goto match; - } + SCLogDebug("content %" PRIu32 " matched at offset %" PRIu32 "", cd->id, match_offset); + det_ctx->buffer_offset = match_offset; + + if ((cd->flags & DETECT_CONTENT_ENDS_WITH) == 0 || match_offset == buffer_len) { + /* Match branch, add replace to the list if needed */ + if (cd->flags & DETECT_CONTENT_REPLACE) { + if (inspection_mode == DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD) { + /* we will need to replace content if match is confirmed + * cast to non-const as replace writes to it. */ + det_ctx->replist = + DetectReplaceAddToList(det_ctx->replist, (uint8_t *)found, cd); + } else { + SCLogWarning("Can't modify payload without packet"); + } + } - SCLogDebug("content %" PRIu32, cd->id); - KEYWORD_PROFILING_END(det_ctx, smd->type, 1); - - /* see if the next buffer keywords match. If not, we will - * search for another occurrence of this content and see - * if the others match then until we run out of matches */ - int r = DetectEngineContentInspectionInternal(det_ctx, ctx, s, smd + 1, p, - f, buffer, buffer_len, stream_start_offset, flags, inspection_mode); - if (r == 1) { - SCReturnInt(1); - } else if (r == -1) { - SCLogDebug("'next sm' said to discontinue this right now"); - SCReturnInt(-1); - } - SCLogDebug("no match for 'next sm'"); + /* if this is the last match we're done */ + if (smd->is_last) { + goto match; + } - /* no match and no reason to look for another instance */ - if ((cd->flags & DETECT_CONTENT_WITHIN_NEXT) == 0) { - SCLogDebug("'next sm' does not depend on me, so we can give up"); - SCReturnInt(-1); - } + SCLogDebug("content %" PRIu32, cd->id); + KEYWORD_PROFILING_END(det_ctx, smd->type, 1); + + /* see if the next buffer keywords match. If not, we will + * search for another occurrence of this content and see + * if the others match then until we run out of matches */ + int r = DetectEngineContentInspectionInternal(det_ctx, ctx, s, smd + 1, p, f, + buffer, buffer_len, stream_start_offset, flags, inspection_mode); + if (r == 1) { + SCReturnInt(1); + } else if (r == -1) { + SCLogDebug("'next sm' said to discontinue this right now"); + SCReturnInt(-1); + } + SCLogDebug("no match for 'next sm'"); - SCLogDebug("'next sm' depends on me %p, lets see what we can do (flags %u)", - cd, cd->flags); - } - /* set the previous match offset to the start of this match + 1 */ - prev_offset = (match_offset - (cd->content_len - 1)); - SCLogDebug("trying to see if there is another match after prev_offset %" PRIu32, - prev_offset); + /* no match and no reason to look for another instance */ + if ((cd->flags & DETECT_CONTENT_WITHIN_NEXT) == 0) { + SCLogDebug("'next sm' does not depend on me, so we can give up"); + SCReturnInt(-1); } - } + SCLogDebug("'next sm' depends on me %p, lets see what we can do (flags %u)", cd, + cd->flags); + } + /* set the previous match offset to the start of this match + 1 */ + prev_offset = (match_offset - (cd->content_len - 1)); + SCLogDebug("trying to see if there is another match after prev_offset %" PRIu32, + prev_offset); } while(1); } else if (smd->type == DETECT_ISDATAAT) { From 32b4423d454e174ace618ac874d6f4ee920407ce Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 25 Sep 2023 10:16:27 +0200 Subject: [PATCH 13/18] detect/isdataat: optimize recursion mismatches Since recursive content matching goes through the buffer from left to right, it is possible to bail early when isdataat is part of the recursive checking. If `isdataat:50,relative` fails for offset 10, it will surely also fail for offset 20. So break inspection in such cases. The exception is for dynamic isdataat, where the value is determined by a prior byte_extract that may be updated during the recursion. --- src/detect-engine-content-inspection.c | 15 +++++++++++++-- src/tests/detect-engine-content-inspection.c | 9 +++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/detect-engine-content-inspection.c b/src/detect-engine-content-inspection.c index ac8a39226ab9..76baead03513 100644 --- a/src/detect-engine-content-inspection.c +++ b/src/detect-engine-content-inspection.c @@ -408,23 +408,34 @@ static int DetectEngineContentInspectionInternal(DetectEngineThreadCtx *det_ctx, SCLogDebug("det_ctx->buffer_offset + dataat %"PRIu32" > %"PRIu32, det_ctx->buffer_offset + dataat, buffer_len); if (id->flags & ISDATAAT_NEGATED) goto match; + if ((id->flags & ISDATAAT_OFFSET_VAR) == 0) { + goto no_match_discontinue; + } goto no_match; } else { SCLogDebug("relative isdataat match"); - if (id->flags & ISDATAAT_NEGATED) + if (id->flags & ISDATAAT_NEGATED) { goto no_match; + } goto match; } } else { if (dataat < buffer_len) { SCLogDebug("absolute isdataat match"); - if (id->flags & ISDATAAT_NEGATED) + if (id->flags & ISDATAAT_NEGATED) { + if ((id->flags & ISDATAAT_OFFSET_VAR) == 0) { + goto no_match_discontinue; + } goto no_match; + } goto match; } else { SCLogDebug("absolute isdataat mismatch, id->isdataat %"PRIu32", buffer_len %"PRIu32"", dataat, buffer_len); if (id->flags & ISDATAAT_NEGATED) goto match; + if ((id->flags & ISDATAAT_OFFSET_VAR) == 0) { + goto no_match_discontinue; + } goto no_match; } } diff --git a/src/tests/detect-engine-content-inspection.c b/src/tests/detect-engine-content-inspection.c index 65a4f578b824..c4e1a3bdff68 100644 --- a/src/tests/detect-engine-content-inspection.c +++ b/src/tests/detect-engine-content-inspection.c @@ -143,6 +143,10 @@ static int DetectEngineContentInspectionTest06(void) { // 6 steps: (1) a, (2) 1st b, (3) c not found, (4) 2nd b, (5) c found, isdataat TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; distance:0; within:1; content:\"c\"; distance:0; within:1; isdataat:!1,relative;", true, 5); TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; distance:0; within:1; content:\"c\"; distance:0; within:1; isdataat:1,relative;", false, 6); + TEST_RUN("abcabc", 6, + "content:\"a\"; content:\"b\"; distance:0; within:1; content:\"c\"; distance:0; " + "within:1; isdataat:10,relative;", + false, 4); TEST_RUN("ababcabc", 8, "content:\"a\"; content:\"b\"; distance:0; within:1; content:\"c\"; distance:0; within:1; isdataat:!1,relative;", true, 7); TEST_RUN("ababcabc", 8, "content:\"a\"; content:\"b\"; distance:0; within:1; content:\"c\"; distance:0; within:1; isdataat:1,relative;", true, 6); @@ -228,6 +232,11 @@ static int DetectEngineContentInspectionTest10(void) { TEST_RUN("x9x9abcdefghi", 13, "content:\"x\"; byte_extract:1,0,data_size,string,relative; isdataat:data_size,relative;", true, 3); TEST_RUN("x9x9abcdefgh", 12, "content:\"x\"; byte_extract:1,0,data_size,string,relative; isdataat:!data_size,relative;", true, 5); TEST_RUN("x9x9abcdefgh", 12, "content:\"x\"; depth:1; byte_extract:1,0,data_size,string,relative; isdataat:!data_size,relative;", false, 3); + /* first isdataat should fail, second succeed */ + TEST_RUN("x9x5abcdef", 10, + "content:\"x\"; byte_extract:1,0,data_size,string,relative; " + "isdataat:data_size,relative;", + true, 5); /* check for super high extracted values */ TEST_RUN("100000000abcdefghi", 18, "byte_extract:0,0,data_size,string; isdataat:data_size;", false, 2); TEST_RUN("100000000abcdefghi", 18, "byte_extract:0,0,data_size,string; isdataat:!data_size;", true, 2); From 45400a7881d10841b225dabbee0bccfc45cefb5f Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 25 Sep 2023 10:53:22 +0200 Subject: [PATCH 14/18] detect/payload: remove unneeded pointer reset DetectEngineThreadCtx::replist is managed elsewhere. --- src/detect-engine-payload.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/detect-engine-payload.c b/src/detect-engine-payload.c index d051303ddbb1..7fc4c0e161d4 100644 --- a/src/detect-engine-payload.c +++ b/src/detect-engine-payload.c @@ -161,8 +161,6 @@ uint8_t DetectEngineInspectPacketPayload(DetectEngineCtx *de_ctx, DetectEngineTh det_ctx->payload_persig_cnt++; det_ctx->payload_persig_size += p->payload_len; #endif - det_ctx->replist = NULL; - const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_arrays[DETECT_SM_LIST_PMATCH], p, f, p->payload, p->payload_len, 0, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD); @@ -198,8 +196,6 @@ static uint8_t DetectEngineInspectStreamUDPPayload(DetectEngineCtx *de_ctx, det_ctx->payload_persig_cnt++; det_ctx->payload_persig_size += p->payload_len; #endif - det_ctx->replist = NULL; - const bool match = DetectEngineContentInspection(de_ctx, det_ctx, s, smd, p, f, p->payload, p->payload_len, 0, DETECT_CI_FLAGS_SINGLE, DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD); From b61923a4db6a1dc8990a4261edf13a666163f354 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 26 Sep 2023 09:34:09 +0200 Subject: [PATCH 15/18] detect/bytemath: pass match ctx directly Adjust includes to enable this. --- src/detect-byte.c | 3 ++- src/detect-bytemath.c | 13 +++++++------ src/detect-bytemath.h | 2 +- src/detect-engine-content-inspection.c | 13 ++++++------- src/detect-engine-register.c | 2 ++ 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/detect-byte.c b/src/detect-byte.c index 19fdc472229e..dd29734a3f3f 100644 --- a/src/detect-byte.c +++ b/src/detect-byte.c @@ -22,10 +22,11 @@ */ #include "suricata-common.h" +#include "rust.h" #include "detect-byte.h" #include "detect-byte-extract.h" #include "detect-bytemath.h" -#include "rust.h" + /** * \brief Used to retrieve args from BM. * diff --git a/src/detect-bytemath.c b/src/detect-bytemath.c index a2880216cffa..3e848f21a5bb 100644 --- a/src/detect-bytemath.c +++ b/src/detect-bytemath.c @@ -29,21 +29,23 @@ #include "threads.h" #include "decode.h" +#include "app-layer-parser.h" +#include "app-layer-protos.h" + #include "detect.h" #include "detect-parse.h" #include "detect-engine.h" #include "detect-engine-mpm.h" #include "detect-engine-state.h" #include "detect-engine-build.h" + +#include "rust-bindings.h" + #include "detect-content.h" #include "detect-pcre.h" #include "detect-byte.h" #include "detect-bytemath.h" -#include "app-layer-parser.h" -#include "app-layer-protos.h" -#include "rust-bindings.h" - #include "flow.h" #include "flow-var.h" #include "flow-util.h" @@ -82,11 +84,10 @@ static inline bool DetectByteMathValidateNbytesOnly(const DetectByteMathData *da (((data->flags & DETECT_BYTEMATH_FLAG_STRING) && nbytes <= 10) || (nbytes <= 4)); } -int DetectByteMathDoMatch(DetectEngineThreadCtx *det_ctx, const SigMatchData *smd, +int DetectByteMathDoMatch(DetectEngineThreadCtx *det_ctx, const DetectByteMathData *data, const Signature *s, const uint8_t *payload, uint16_t payload_len, uint8_t nbytes, uint64_t rvalue, uint64_t *value, uint8_t endian) { - const DetectByteMathData *data = (DetectByteMathData *)smd->ctx; if (payload_len == 0) { return 0; } diff --git a/src/detect-bytemath.h b/src/detect-bytemath.h index 672f799ca4f5..4fbc9ae5ce15 100644 --- a/src/detect-bytemath.h +++ b/src/detect-bytemath.h @@ -27,7 +27,7 @@ void DetectBytemathRegister(void); SigMatch *DetectByteMathRetrieveSMVar(const char *, const Signature *); -int DetectByteMathDoMatch(DetectEngineThreadCtx *, const SigMatchData *, const Signature *, +int DetectByteMathDoMatch(DetectEngineThreadCtx *, const DetectByteMathData *, const Signature *, const uint8_t *, uint16_t, uint8_t, uint64_t, uint64_t *, uint8_t); #endif /* __DETECT_BYTEMATH_H__ */ diff --git a/src/detect-engine-content-inspection.c b/src/detect-engine-content-inspection.c index 76baead03513..5d6ad2be5629 100644 --- a/src/detect-engine-content-inspection.c +++ b/src/detect-engine-content-inspection.c @@ -25,12 +25,14 @@ #include "suricata-common.h" #include "suricata.h" - #include "decode.h" #include "detect.h" #include "detect-engine.h" #include "detect-parse.h" + +#include "rust.h" + #include "detect-asn1.h" #include "detect-content.h" #include "detect-pcre.h" @@ -60,8 +62,6 @@ #include "util-unittest-helper.h" #include "util-profiling.h" -#include "rust.h" - #ifdef HAVE_LUA #include "util-lua.h" #endif @@ -569,17 +569,16 @@ static int DetectEngineContentInspectionInternal(DetectEngineThreadCtx *det_ctx, } else if (smd->type == DETECT_BYTEMATH) { - DetectByteMathData *bmd = (DetectByteMathData *)smd->ctx; + const DetectByteMathData *bmd = (const DetectByteMathData *)smd->ctx; uint8_t endian = bmd->endian; /* if we have dce enabled we will have to use the endianness * specified by the dce header */ if ((bmd->flags & DETECT_BYTEMATH_FLAG_ENDIAN) && endian == (int)EndianDCE && flags & (DETECT_CI_FLAGS_DCE_LE | DETECT_CI_FLAGS_DCE_BE)) { - /* enable the endianness flag temporarily. once we are done * processing we reset the flags to the original value*/ - endian |= (uint8_t)((flags & DETECT_CI_FLAGS_DCE_LE) ? LittleEndian : BigEndian); + endian = (uint8_t)((flags & DETECT_CI_FLAGS_DCE_LE) ? LittleEndian : BigEndian); } uint64_t rvalue; if (bmd->flags & DETECT_BYTEMATH_FLAG_RVALUE_VAR) { @@ -596,7 +595,7 @@ static int DetectEngineContentInspectionInternal(DetectEngineThreadCtx *det_ctx, } DEBUG_VALIDATE_BUG_ON(buffer_len > UINT16_MAX); - if (DetectByteMathDoMatch(det_ctx, smd, s, buffer, (uint16_t)buffer_len, nbytes, rvalue, + if (DetectByteMathDoMatch(det_ctx, bmd, s, buffer, (uint16_t)buffer_len, nbytes, rvalue, &det_ctx->byte_values[bmd->local_id], endian) != 1) { goto no_match; } diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index 0f459eccb67b..b27f5a511f9c 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -43,6 +43,8 @@ #include "detect-engine-threshold.h" #include "detect-engine-prefilter.h" +#include "rust.h" + #include "detect-engine-payload.h" #include "detect-engine-dcepayload.h" #include "detect-dns-opcode.h" From 8de4a76b2e2a0d7f578cf6d45859b8ed19a44dca Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 26 Sep 2023 10:10:14 +0200 Subject: [PATCH 16/18] detect: optimize struct layout Move reference count to top of DetectEngineThreadCtx, to move it to the same cache line as the other members that are checked first in Detect(). --- src/detect.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/detect.h b/src/detect.h index 9230f501d697..2b634e761701 100644 --- a/src/detect.h +++ b/src/detect.h @@ -1082,6 +1082,8 @@ typedef struct DetectEngineThreadCtx_ { * on this being the first member */ uint32_t tenant_id; + SC_ATOMIC_DECLARE(int, so_far_used_by_detect); + /* the thread to which this detection engine thread belongs */ ThreadVars *tv; @@ -1157,8 +1159,6 @@ typedef struct DetectEngineThreadCtx_ { uint16_t alert_queue_capacity; PacketAlert *alert_queue; - SC_ATOMIC_DECLARE(int, so_far_used_by_detect); - /** array of signature pointers we're going to inspect in the detection * loop. */ Signature **match_array; From 6a3d9c3dd20f8bd61d6be80b12a050e76b737f16 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 26 Sep 2023 10:10:52 +0200 Subject: [PATCH 17/18] detect/content-inspect: optimize struct layout Move members used by DetectEngineContentInspection() to the same cache line. --- src/detect.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/detect.h b/src/detect.h index 2b634e761701..36e4e2ba3b25 100644 --- a/src/detect.h +++ b/src/detect.h @@ -1112,6 +1112,17 @@ typedef struct DetectEngineThreadCtx_ { * points to 1 byte after the start of the last pcre match if a pcre match happened. */ uint32_t pcre_match_start_offset; + /** SPM thread context used for scanning. This has been cloned from the + * prototype held by DetectEngineCtx. */ + SpmThreadCtx *spm_thread_ctx; + + /* byte_* values */ + uint64_t *byte_values; + + uint8_t *base64_decoded; + int base64_decoded_len; + int base64_decoded_len_max; + /* counter for the filestore array below -- up here for cache reasons. */ uint16_t filestore_cnt; @@ -1177,13 +1188,6 @@ typedef struct DetectEngineThreadCtx_ { MpmThreadCtx mtc; /**< thread ctx for the mpm */ PrefilterRuleStore pmq; - /** SPM thread context used for scanning. This has been cloned from the - * prototype held by DetectEngineCtx. */ - SpmThreadCtx *spm_thread_ctx; - - /* byte_* values */ - uint64_t *byte_values; - /* string to replace */ DetectReplaceList *replist; /* vars to store in post match function */ @@ -1205,10 +1209,6 @@ typedef struct DetectEngineThreadCtx_ { int global_keyword_ctxs_size; void **global_keyword_ctxs_array; - uint8_t *base64_decoded; - int base64_decoded_len; - int base64_decoded_len_max; - AppLayerDecoderEvents *decoder_events; uint16_t events; From 6d3bfa95fd7e5d30cff1429d8d313e6454ae49bb Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 9 Oct 2023 09:30:38 +0200 Subject: [PATCH 18/18] detect/uri: remove tests that are now done elsewhere Core logic of the tests moved to content inspection code in separate commit. --- src/tests/detect-http-uri.c | 182 ------------------------------------ 1 file changed, 182 deletions(-) diff --git a/src/tests/detect-http-uri.c b/src/tests/detect-http-uri.c index 8c60d430588e..b33d09fd64c1 100644 --- a/src/tests/detect-http-uri.c +++ b/src/tests/detect-http-uri.c @@ -2803,186 +2803,6 @@ static int UriTestSig29(void) return result; } -static int UriTestSig30(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP1; - - StreamTcpInitConfig(true); - - 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:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"_b5ig\"; offset:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - int r = AppLayerParserParse( - NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(true); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig31(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP1; - - StreamTcpInitConfig(true); - - 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:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"his\"; depth:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - int r = AppLayerParserParse( - NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(true); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - static int UriTestSig32(void) { int result = 0; @@ -6793,8 +6613,6 @@ static void DetectHttpUriRegisterTests (void) UtRegisterTest("UriTestSig28", UriTestSig28); UtRegisterTest("UriTestSig29", UriTestSig29); - UtRegisterTest("UriTestSig30", UriTestSig30); - UtRegisterTest("UriTestSig31", UriTestSig31); UtRegisterTest("UriTestSig32", UriTestSig32); UtRegisterTest("UriTestSig33", UriTestSig33); UtRegisterTest("UriTestSig34", UriTestSig34);