From a4239d433a9804f0893a1e8989211e7ee8b82fef Mon Sep 17 00:00:00 2001 From: Jeff Lucovsky Date: Sun, 16 Oct 2022 10:13:19 -0400 Subject: [PATCH] detect/bsize: Validate bsize values after parsing Issue: 2982 This commit moves bsize validation with respect to content matches to the post-parse validation stage. This allows bsize to consider all content-related values, including those that follow the bsize keyword. --- src/detect-bsize.c | 80 ++++++++++++++++++++++++---------------- src/detect-bsize.h | 1 + src/detect-parse.c | 5 +++ src/tests/detect-bsize.c | 2 + 4 files changed, 56 insertions(+), 32 deletions(-) diff --git a/src/detect-bsize.c b/src/detect-bsize.c index c4719632ed..8e4405073f 100644 --- a/src/detect-bsize.c +++ b/src/detect-bsize.c @@ -40,10 +40,58 @@ /*prototypes*/ static int DetectBsizeSetup (DetectEngineCtx *, Signature *, const char *); static void DetectBsizeFree (DetectEngineCtx *, void *); +static int SigParseGetMaxBsize(DetectU64Data *bsz); #ifdef UNITTESTS static void DetectBsizeRegisterTests (void); #endif +bool DetectBsizeValidateContentCallback(Signature *s, int list) +{ + int bsize = -1; + DetectU64Data *bsz; + for (const SigMatch *sm = s->init_data->smlists[list]; sm != NULL; sm = sm->next) { + if (sm->type == DETECT_BSIZE) { + bsz = (DetectU64Data *)sm->ctx; + bsize = SigParseGetMaxBsize(bsz); + break; + } + } + + if (bsize == -1) { + return true; + } + + uint64_t needed; + if (bsize >= 0) { + int len, offset; + SigParseRequiredContentSize(s, bsize, list, &len, &offset); + SCLogDebug("bsize: %d; len: %d; offset: %d [%s]", bsize, len, offset, s->sig_str); + needed = len; + if (len > bsize) { + goto value_error; + } + if ((len + offset) > bsize) { + needed += offset; + goto value_error; + } + } + + return true; +value_error: + if (bsz->mode == DETECT_UINT_RA) { + SCLogError(SC_ERR_INVALID_SIGNATURE, + "signature can't match as required content length %" PRIu64 + " exceeds bsize range: %" PRIu64 "-%" PRIu64, + needed, bsz->arg1, bsz->arg2); + } else { + SCLogError(SC_ERR_INVALID_SIGNATURE, + "signature can't match as required content length %" PRIu64 " exceeds bsize value: " + "%" PRIu64, + needed, bsz->arg1); + } + return false; +} + /** * \brief Registration function for bsize: keyword */ @@ -61,8 +109,6 @@ void DetectBsizeRegister(void) #endif } -static int SigParseGetMaxBsize(DetectU64Data *bsz); - /** \brief bsize match function * * \param ctx match ctx @@ -167,23 +213,6 @@ static int DetectBsizeSetup (DetectEngineCtx *de_ctx, Signature *s, const char * if (bsz == NULL) goto error; - const int bsize = SigParseGetMaxBsize(bsz); - - uint64_t needed; - if (bsize >= 0) { - int len, offset; - SigParseRequiredContentSize(s, bsize, list, &len, &offset); - SCLogDebug("bsize: %d; len: %d; offset: %d [%s]", bsize, len, offset, s->sig_str); - needed = len; - if (len > bsize) { - goto value_error; - } - if ((len + offset) > bsize) { - needed += offset; - goto value_error; - } - } - sm = SigMatchAlloc(); if (sm == NULL) goto error; @@ -194,19 +223,6 @@ static int DetectBsizeSetup (DetectEngineCtx *de_ctx, Signature *s, const char * SCReturnInt(0); -value_error: - if (bsz->mode == DETECT_UINT_RA) { - SCLogError(SC_ERR_INVALID_SIGNATURE, - "signature can't match as required content length %" PRIu64 - " exceeds bsize range: %" PRIu64 "-%" PRIu64, - needed, bsz->arg1, bsz->arg2); - } else { - SCLogError(SC_ERR_INVALID_SIGNATURE, - "signature can't match as required content length %" PRIu64 " exceeds bsize value: " - "%" PRIu64, - needed, bsz->arg1); - } - error: DetectBsizeFree(de_ctx, bsz); SCReturnInt(-1); diff --git a/src/detect-bsize.h b/src/detect-bsize.h index ad51b62cf9..1535c6fdb2 100644 --- a/src/detect-bsize.h +++ b/src/detect-bsize.h @@ -26,5 +26,6 @@ void DetectBsizeRegister(void); int DetectBsizeMatch(const SigMatchCtx *ctx, const uint64_t buffer_size, bool eof); +bool DetectBsizeValidateContentCallback(Signature *s, int list); #endif /* __DETECT_URILEN_H__ */ diff --git a/src/detect-parse.c b/src/detect-parse.c index b6dbc8bb34..061265cffe 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -34,6 +34,7 @@ #include "detect-engine-build.h" #include "detect-content.h" +#include "detect-bsize.h" #include "detect-pcre.h" #include "detect-uricontent.h" #include "detect-reference.h" @@ -1727,6 +1728,10 @@ static int SigValidate(DetectEngineCtx *de_ctx, Signature *s) if (!DetectEngineBufferRunValidateCallback(de_ctx, x, s, &de_ctx->sigerror)) { SCReturnInt(0); } + + if (!DetectBsizeValidateContentCallback(s, x)) { + SCReturnInt(0); + } } } diff --git a/src/tests/detect-bsize.c b/src/tests/detect-bsize.c index bf6a192a8d..2fcd656589 100644 --- a/src/tests/detect-bsize.c +++ b/src/tests/detect-bsize.c @@ -156,6 +156,8 @@ static int DetectBsizeSigTest01(void) "sid:17;)"); TEST_FAIL("alert http any any -> any any (http.uri; content:\"abc\"; offset:65535; bsize:3; " "sid:18;)"); + TEST_FAIL("alert http any any -> any any (http.user_agent; content:\"Suricata-UA\"; bsize:11; " + "content:!\"abc\"; distance:2; within:3; sid: 19;)"); PASS; }