diff --git a/src/detect-bsize.c b/src/detect-bsize.c index 6cb63a6e00..c4719632ed 100644 --- a/src/detect-bsize.c +++ b/src/detect-bsize.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2020 Open Information Security Foundation +/* Copyright (C) 2017-2022 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 @@ -61,6 +61,8 @@ void DetectBsizeRegister(void) #endif } +static int SigParseGetMaxBsize(DetectU64Data *bsz); + /** \brief bsize match function * * \param ctx match ctx @@ -124,12 +126,27 @@ static DetectU64Data *DetectBsizeParse(const char *str) return DetectU64Parse(str); } +static int SigParseGetMaxBsize(DetectU64Data *bsz) +{ + switch (bsz->mode) { + case DETECT_UINT_LT: + case DETECT_UINT_EQ: + return bsz->arg1; + case DETECT_UINT_RA: + return bsz->arg2; + case DETECT_UINT_GT: + default: + SCReturnInt(-2); + } + SCReturnInt(-1); +} + /** * \brief this function is used to parse bsize data into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature - * \param bsizestr pointer to the user provided bsize options + * \param sizestr pointer to the user provided bsize options * * \retval 0 on Success * \retval -1 on Failure @@ -149,6 +166,24 @@ static int DetectBsizeSetup (DetectEngineCtx *de_ctx, Signature *s, const char * DetectU64Data *bsz = DetectBsizeParse(sizestr); 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; @@ -159,6 +194,19 @@ 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/tests/detect-bsize.c b/src/tests/detect-bsize.c index 524d6d192e..bf6a192a8d 100644 --- a/src/tests/detect-bsize.c +++ b/src/tests/detect-bsize.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2020 Open Information Security Foundation +/* Copyright (C) 2017-2022 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 @@ -118,41 +118,42 @@ static int DetectBsizeTest04(void) static int DetectBsizeSigTest01(void) { -#if 0 TEST_OK("alert http any any -> any any (http_request_line; bsize:10; sid:1;)"); TEST_OK("alert http any any -> any any (file_data; bsize:>1000; sid:2;)"); - TEST_FAIL("alert tcp any any -> any any (content:\"abc\"; bsize:10; sid:3;)"); - TEST_FAIL("alert http any any -> any any (content:\"GET\"; http_method; bsize:10; sid:4;)"); - TEST_FAIL("alert http any any -> any any (http_request_line; content:\"GET\"; bsize:<10>; sid:5;)"); - /* bsize validation with buffer */ TEST_OK("alert http any any -> any any (http.uri; content:\"/index.php\"; bsize:>1024; " "sid:6;)"); - TEST_OK("alert http any any -> any any (http.uri; content:\"abdcef\"; content: \"g\"; bsize:1; " - "sid:7;)"); - TEST_OK("alert http any any -> any any (http.uri; content:\"abdcef\"; content: \"g\"; bsize:4; " - "sid:8;)"); TEST_OK("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:<20; " " sid:9;)"); TEST_OK("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:15<>25; " "sid:10;)"); + TEST_OK("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:10<>15; " + "sid:13;)"); + + TEST_FAIL("alert tcp any any -> any any (content:\"abc\"; bsize:10; sid:3;)"); + TEST_FAIL("alert http any any -> any any (content:\"GET\"; http_method; bsize:10; sid:4;)"); + TEST_FAIL("alert http any any -> any any (http_request_line; content:\"GET\"; bsize:<10>; " + "sid:5;)"); + TEST_FAIL("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:2; " "sid:11;)"); TEST_FAIL("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:<13; " "sid:12;)"); - TEST_OK("alert http any any -> any any (http.uri; content:\"abcdefgh123456\"; bsize:10<>15; " - "sid:13;)"); + TEST_FAIL( + "alert http any any -> any any (http.uri; content:\"abcdef\"; content: \"g\"; bsize:1; " + "sid:7;)"); + TEST_FAIL( + "alert http any any -> any any (http.uri; content:\"abcdef\"; content: \"g\"; bsize:4; " + "sid:8;)"); TEST_FAIL("alert http any any -> any any (http.uri; content:\"abcdefghi123456\"; offset:12; " "bsize:3; sid:14;)"); TEST_FAIL("alert http any any -> any any (http.uri; content:\"abc\"; offset:3; depth:3; " "bsize:3; sid:15;)"); - TEST_FAIL("alert http any any -> any any (http.uri; content:\"abdcef\"; content: \"gh\"; " + TEST_FAIL("alert http any any -> any any (http.uri; content:\"abcdef\"; content: \"gh\"; " "bsize:1; sid:16;)"); TEST_FAIL("alert http any any -> any any (http.uri; content:\"abc\"; offset:3; bsize:3; " "sid:17;)"); - -#endif TEST_FAIL("alert http any any -> any any (http.uri; content:\"abc\"; offset:65535; bsize:3; " "sid:18;)"); PASS;