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*/
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);

@ -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__ */

@ -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);
}
}
}

@ -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;
}

Loading…
Cancel
Save