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.
pull/8165/head
Jeff Lucovsky 3 years ago committed by Victor Julien
parent 9d73777a46
commit a4239d433a

@ -40,10 +40,58 @@
/*prototypes*/ /*prototypes*/
static int DetectBsizeSetup (DetectEngineCtx *, Signature *, const char *); static int DetectBsizeSetup (DetectEngineCtx *, Signature *, const char *);
static void DetectBsizeFree (DetectEngineCtx *, void *); static void DetectBsizeFree (DetectEngineCtx *, void *);
static int SigParseGetMaxBsize(DetectU64Data *bsz);
#ifdef UNITTESTS #ifdef UNITTESTS
static void DetectBsizeRegisterTests (void); static void DetectBsizeRegisterTests (void);
#endif #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 * \brief Registration function for bsize: keyword
*/ */
@ -61,8 +109,6 @@ void DetectBsizeRegister(void)
#endif #endif
} }
static int SigParseGetMaxBsize(DetectU64Data *bsz);
/** \brief bsize match function /** \brief bsize match function
* *
* \param ctx match ctx * \param ctx match ctx
@ -167,23 +213,6 @@ static int DetectBsizeSetup (DetectEngineCtx *de_ctx, Signature *s, const char *
if (bsz == NULL) if (bsz == NULL)
goto error; 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(); sm = SigMatchAlloc();
if (sm == NULL) if (sm == NULL)
goto error; goto error;
@ -194,19 +223,6 @@ static int DetectBsizeSetup (DetectEngineCtx *de_ctx, Signature *s, const char *
SCReturnInt(0); 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: error:
DetectBsizeFree(de_ctx, bsz); DetectBsizeFree(de_ctx, bsz);
SCReturnInt(-1); SCReturnInt(-1);

@ -26,5 +26,6 @@
void DetectBsizeRegister(void); void DetectBsizeRegister(void);
int DetectBsizeMatch(const SigMatchCtx *ctx, const uint64_t buffer_size, bool eof); int DetectBsizeMatch(const SigMatchCtx *ctx, const uint64_t buffer_size, bool eof);
bool DetectBsizeValidateContentCallback(Signature *s, int list);
#endif /* __DETECT_URILEN_H__ */ #endif /* __DETECT_URILEN_H__ */

@ -34,6 +34,7 @@
#include "detect-engine-build.h" #include "detect-engine-build.h"
#include "detect-content.h" #include "detect-content.h"
#include "detect-bsize.h"
#include "detect-pcre.h" #include "detect-pcre.h"
#include "detect-uricontent.h" #include "detect-uricontent.h"
#include "detect-reference.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)) { if (!DetectEngineBufferRunValidateCallback(de_ctx, x, s, &de_ctx->sigerror)) {
SCReturnInt(0); SCReturnInt(0);
} }
if (!DetectBsizeValidateContentCallback(s, x)) {
SCReturnInt(0);
}
} }
} }

@ -156,6 +156,8 @@ static int DetectBsizeSigTest01(void)
"sid:17;)"); "sid:17;)");
TEST_FAIL("alert http any any -> any any (http.uri; content:\"abc\"; offset:65535; bsize:3; " TEST_FAIL("alert http any any -> any any (http.uri; content:\"abc\"; offset:65535; bsize:3; "
"sid:18;)"); "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; PASS;
} }

Loading…
Cancel
Save