From: Maurizio Abba Date: Tue, 10 Apr 2018 14:37:41 +0000 (+0100) Subject: detect: fix buffer length to uint32 X-Git-Tag: suricata-4.1.0-rc1~125 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d2bf7a3ba9698ded982683e17837ea08f3ddecba;p=thirdparty%2Fsuricata.git detect: fix buffer length to uint32 There is a difference in the size of the buffer length as passed from the content buffers (cfr HttpReassembledBody.buffer_len) and the buflen variable passed to mpm primitives. This can cause a misdetection whenever the bufferlen is multiple of 65536 (as uint16(X*65536) == 0). Increasing the buflen variable type to uint32 solves the issue (this does not cause any issue with primitives, they all accept uint32). --- diff --git a/src/util-mpm-ac-bs.c b/src/util-mpm-ac-bs.c index ded1ad18fa..6f0a656d4a 100644 --- a/src/util-mpm-ac-bs.c +++ b/src/util-mpm-ac-bs.c @@ -70,7 +70,7 @@ int SCACBSAddPatternCS(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t); int SCACBSPreparePatterns(MpmCtx *mpm_ctx); uint32_t SCACBSSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PrefilterRuleStore *pmq, const uint8_t *buf, uint16_t buflen); + PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen); void SCACBSPrintInfo(MpmCtx *mpm_ctx); void SCACBSPrintSearchStats(MpmThreadCtx *mpm_thread_ctx); void SCACBSRegisterTests(void); @@ -1143,10 +1143,10 @@ void SCACBSDestroyCtx(MpmCtx *mpm_ctx) * \retval matches Match count. */ uint32_t SCACBSSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PrefilterRuleStore *pmq, const uint8_t *buf, uint16_t buflen) + PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen) { const SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - int i = 0; + uint32_t i = 0; int matches = 0; uint8_t buf_local; diff --git a/src/util-mpm-ac-tile-small.c b/src/util-mpm-ac-tile-small.c index a5e1ef0eac..062e13c66b 100644 --- a/src/util-mpm-ac-tile-small.c +++ b/src/util-mpm-ac-tile-small.c @@ -32,9 +32,9 @@ /* This function handles (ctx->state_count < 32767) */ uint32_t FUNC_NAME(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PrefilterRuleStore *pmq, const uint8_t *buf, uint16_t buflen) + PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen) { - int i = 0; + uint32_t i = 0; int matches = 0; uint8_t mpm_bitarray[ctx->mpm_bitarray_size]; diff --git a/src/util-mpm-ac-tile.c b/src/util-mpm-ac-tile.c index 07d791ad1a..0d8c8887af 100644 --- a/src/util-mpm-ac-tile.c +++ b/src/util-mpm-ac-tile.c @@ -93,51 +93,51 @@ int SCACTileAddPatternCS(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, int SCACTilePreparePatterns(MpmCtx *mpm_ctx); uint32_t SCACTileSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, - uint16_t buflen); + uint32_t buflen); void SCACTilePrintInfo(MpmCtx *mpm_ctx); void SCACTilePrintSearchStats(MpmThreadCtx *mpm_thread_ctx); void SCACTileRegisterTests(void); uint32_t SCACTileSearchLarge(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen); + const uint8_t *buf, uint32_t buflen); uint32_t SCACTileSearchSmall256(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen); + const uint8_t *buf, uint32_t buflen); uint32_t SCACTileSearchSmall128(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen); + const uint8_t *buf, uint32_t buflen); uint32_t SCACTileSearchSmall64(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen); + const uint8_t *buf, uint32_t buflen); uint32_t SCACTileSearchSmall32(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen); + const uint8_t *buf, uint32_t buflen); uint32_t SCACTileSearchSmall16(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen); + const uint8_t *buf, uint32_t buflen); uint32_t SCACTileSearchSmall8(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen); + const uint8_t *buf, uint32_t buflen); uint32_t SCACTileSearchTiny256(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen); + const uint8_t *buf, uint32_t buflen); uint32_t SCACTileSearchTiny128(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen); + const uint8_t *buf, uint32_t buflen); uint32_t SCACTileSearchTiny64(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen); + const uint8_t *buf, uint32_t buflen); uint32_t SCACTileSearchTiny32(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen); + const uint8_t *buf, uint32_t buflen); uint32_t SCACTileSearchTiny16(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen); + const uint8_t *buf, uint32_t buflen); uint32_t SCACTileSearchTiny8(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen); + const uint8_t *buf, uint32_t buflen); static void SCACTileDestroyInitCtx(MpmCtx *mpm_ctx); @@ -1175,7 +1175,7 @@ void SCACTileDestroyCtx(MpmCtx *mpm_ctx) #endif static int CheckMatch(const SCACTileSearchCtx *ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen, + const uint8_t *buf, uint32_t buflen, uint16_t state, int i, int matches, uint8_t *mpm_bitarray) { @@ -1242,7 +1242,7 @@ static int CheckMatch(const SCACTileSearchCtx *ctx, PrefilterRuleStore *pmq, * \retval matches Match count. */ uint32_t SCACTileSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PrefilterRuleStore *pmq, const uint8_t *buf, uint16_t buflen) + PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen) { const SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; @@ -1256,9 +1256,9 @@ uint32_t SCACTileSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, /* This function handles (ctx->state_count >= 32767) */ uint32_t SCACTileSearchLarge(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, - const uint8_t *buf, uint16_t buflen) + const uint8_t *buf, uint32_t buflen) { - int i = 0; + uint32_t i = 0; int matches = 0; uint8_t mpm_bitarray[ctx->mpm_bitarray_size]; diff --git a/src/util-mpm-ac-tile.h b/src/util-mpm-ac-tile.h index 5e3b166f1c..b594f63fed 100644 --- a/src/util-mpm-ac-tile.h +++ b/src/util-mpm-ac-tile.h @@ -67,7 +67,7 @@ typedef struct SCACTileCtx_ { * 32 bits. */ uint32_t (*Search)(const struct SCACTileSearchCtx_ *ctx, struct MpmThreadCtx_ *, - PrefilterRuleStore *, const uint8_t *, uint16_t); + PrefilterRuleStore *, const uint8_t *, uint32_t); /* Function to set the next state based on size of next state * (bytes_per_state). @@ -120,7 +120,7 @@ typedef struct SCACTileSearchCtx_ { * 32 bits. */ uint32_t (*Search)(const struct SCACTileSearchCtx_ *ctx, struct MpmThreadCtx_ *, - PrefilterRuleStore *, const uint8_t *, uint16_t); + PrefilterRuleStore *, const uint8_t *, uint32_t); /* Convert input character to matching alphabet */ uint8_t translate_table[256]; diff --git a/src/util-mpm-ac.c b/src/util-mpm-ac.c index 42666f111d..e972cb6f4e 100644 --- a/src/util-mpm-ac.c +++ b/src/util-mpm-ac.c @@ -70,7 +70,7 @@ int SCACAddPatternCS(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t); int SCACPreparePatterns(MpmCtx *mpm_ctx); uint32_t SCACSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PrefilterRuleStore *pmq, const uint8_t *buf, uint16_t buflen); + PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen); void SCACPrintInfo(MpmCtx *mpm_ctx); void SCACPrintSearchStats(MpmThreadCtx *mpm_thread_ctx); void SCACRegisterTests(void); @@ -1027,10 +1027,10 @@ void SCACDestroyCtx(MpmCtx *mpm_ctx) * \retval matches Match count. */ uint32_t SCACSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PrefilterRuleStore *pmq, const uint8_t *buf, uint16_t buflen) + PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen) { const SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - int i = 0; + uint32_t i = 0; int matches = 0; /* \todo tried loop unrolling with register var, with no perf increase. Need diff --git a/src/util-mpm-hs.c b/src/util-mpm-hs.c index 364ebc6b63..eca73f7cba 100644 --- a/src/util-mpm-hs.c +++ b/src/util-mpm-hs.c @@ -56,7 +56,7 @@ int SCHSAddPatternCS(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t); int SCHSPreparePatterns(MpmCtx *mpm_ctx); uint32_t SCHSSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PrefilterRuleStore *pmq, const uint8_t *buf, const uint16_t buflen); + PrefilterRuleStore *pmq, const uint8_t *buf, const uint32_t buflen); void SCHSPrintInfo(MpmCtx *mpm_ctx); void SCHSPrintSearchStats(MpmThreadCtx *mpm_thread_ctx); void SCHSRegisterTests(void); @@ -917,7 +917,7 @@ static int SCHSMatchEvent(unsigned int id, unsigned long long from, * \retval matches Match count. */ uint32_t SCHSSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PrefilterRuleStore *pmq, const uint8_t *buf, const uint16_t buflen) + PrefilterRuleStore *pmq, const uint8_t *buf, const uint32_t buflen) { uint32_t ret = 0; SCHSCtx *ctx = (SCHSCtx *)mpm_ctx->ctx; diff --git a/src/util-mpm.h b/src/util-mpm.h index d6a1605139..3a48021697 100644 --- a/src/util-mpm.h +++ b/src/util-mpm.h @@ -155,7 +155,7 @@ typedef struct MpmTableElmt_ { int (*AddPattern)(struct MpmCtx_ *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t); int (*AddPatternNocase)(struct MpmCtx_ *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t); int (*Prepare)(struct MpmCtx_ *); - uint32_t (*Search)(const struct MpmCtx_ *, struct MpmThreadCtx_ *, PrefilterRuleStore *, const uint8_t *, uint16_t); + uint32_t (*Search)(const struct MpmCtx_ *, struct MpmThreadCtx_ *, PrefilterRuleStore *, const uint8_t *, uint32_t); void (*PrintCtx)(struct MpmCtx_ *); void (*PrintThreadCtx)(struct MpmThreadCtx_ *); void (*RegisterUnittests)(void); diff --git a/src/util-spm-bm.c b/src/util-spm-bm.c index 906927697e..234d169597 100644 --- a/src/util-spm-bm.c +++ b/src/util-spm-bm.c @@ -303,12 +303,13 @@ static void PreBmGsNocase(const uint8_t *x, uint16_t m, uint16_t *bmGs) * * \retval ptr to start of the match; NULL if no match */ -uint8_t *BoyerMoore(const uint8_t *x, uint16_t m, const uint8_t *y, int32_t n, BmCtx *bm_ctx) +uint8_t *BoyerMoore(const uint8_t *x, uint16_t m, const uint8_t *y, uint32_t n, BmCtx *bm_ctx) { uint16_t *bmGs = bm_ctx->bmGs; uint16_t *bmBc = bm_ctx->bmBc; - int i, j, m1, m2; + int i, j, m1, m2; + int32_t int_n; #if 0 printf("\nBad:\n"); for (i=0;i= 0 && x[i] == y[i + j]; --i); - - if (i < 0) { - return (uint8_t *)(y + j); - //j += bmGs[0]; - } else { - // printf("%c", y[i+j]); - j += (m1 = bmGs[i]) > (m2 = bmBc[y[i + j]] - m + 1 + i)? m1: m2; -// printf("%d, %d\n", m1, m2); - } - } - return NULL; + // force casting to int32_t (if possible) + int_n = unlikely(n > INT32_MAX) ? INT32_MAX : n; + j = 0; + while (j <= int_n - m ) { + for (i = m - 1; i >= 0 && x[i] == y[i + j]; --i); + + if (i < 0) { + return (uint8_t *)(y + j); + //j += bmGs[0]; + } else { +// printf("%c", y[i+j]); + j += (m1 = bmGs[i]) > (m2 = bmBc[y[i + j]] - m + 1 + i)? m1: m2; +// printf("%d, %d\n", m1, m2); + } + } + return NULL; } @@ -352,11 +354,12 @@ uint8_t *BoyerMoore(const uint8_t *x, uint16_t m, const uint8_t *y, int32_t n, B * * \retval ptr to start of the match; NULL if no match */ -uint8_t *BoyerMooreNocase(const uint8_t *x, uint16_t m, const uint8_t *y, int32_t n, BmCtx *bm_ctx) +uint8_t *BoyerMooreNocase(const uint8_t *x, uint16_t m, const uint8_t *y, uint32_t n, BmCtx *bm_ctx) { uint16_t *bmGs = bm_ctx->bmGs; uint16_t *bmBc = bm_ctx->bmBc; int i, j, m1, m2; + int32_t int_n; #if 0 printf("\nBad:\n"); for (i=0;i INT32_MAX) ? INT32_MAX : n; j = 0; - while (j <= n - m ) { - /* x is stored in lowercase. */ + while (j <= int_n - m ) { + /* x is stored in lowercase. */ for (i = m - 1; i >= 0 && x[i] == u8_tolower(y[i + j]); --i); if (i < 0) { return (uint8_t *)(y + j); } else { - j += (m1=bmGs[i]) > (m2=bmBc[u8_tolower(y[i + j])] - m + 1 + i)?m1:m2; + j += (m1 = bmGs[i]) > (m2 = bmBc[u8_tolower(y[i + j])] - m + 1 + i)? + m1: m2; } - } - return NULL; + } + return NULL; } typedef struct SpmBmCtx_ { @@ -448,7 +454,7 @@ static void BMDestroyCtx(SpmCtx *ctx) } static uint8_t *BMScan(const SpmCtx *ctx, SpmThreadCtx *thread_ctx, - const uint8_t *haystack, uint16_t haystack_len) + const uint8_t *haystack, uint32_t haystack_len) { const SpmBmCtx *sctx = ctx->ctx; diff --git a/src/util-spm-bm.h b/src/util-spm-bm.h index a1c6b4c315..b792be33dc 100644 --- a/src/util-spm-bm.h +++ b/src/util-spm-bm.h @@ -41,8 +41,8 @@ BmCtx *BoyerMooreCtxInit(const uint8_t *needle, uint16_t needle_len); BmCtx *BoyerMooreNocaseCtxInit(uint8_t *needle, uint16_t needle_len); void BoyerMooreCtxToNocase(BmCtx *, uint8_t *, uint16_t); -uint8_t *BoyerMoore(const uint8_t *x, uint16_t m, const uint8_t *y, int32_t n, BmCtx *bm_ctx); -uint8_t *BoyerMooreNocase(const uint8_t *x, uint16_t m, const uint8_t *y, int32_t n, BmCtx *bm_ctx); +uint8_t *BoyerMoore(const uint8_t *x, uint16_t m, const uint8_t *y, uint32_t n, BmCtx *bm_ctx); +uint8_t *BoyerMooreNocase(const uint8_t *x, uint16_t m, const uint8_t *y, uint32_t n, BmCtx *bm_ctx); void BoyerMooreCtxDeInit(BmCtx *); void SpmBMRegister(void); diff --git a/src/util-spm-hs.c b/src/util-spm-hs.c index 898b6e9067..b45dc8d936 100644 --- a/src/util-spm-hs.c +++ b/src/util-spm-hs.c @@ -136,7 +136,7 @@ static SpmCtx *HSInitCtx(const uint8_t *needle, uint16_t needle_len, int nocase, } static uint8_t *HSScan(const SpmCtx *ctx, SpmThreadCtx *thread_ctx, - const uint8_t *haystack, uint16_t haystack_len) + const uint8_t *haystack, uint32_t haystack_len) { const SpmHsCtx *sctx = ctx->ctx; hs_scratch_t *scratch = thread_ctx->ctx; diff --git a/src/util-spm.c b/src/util-spm.c index 7cdbdf2964..e6fcf3dda7 100644 --- a/src/util-spm.c +++ b/src/util-spm.c @@ -184,7 +184,7 @@ void SpmDestroyCtx(SpmCtx *ctx) } uint8_t *SpmScan(const SpmCtx *ctx, SpmThreadCtx *thread_ctx, - const uint8_t *haystack, uint16_t haystack_len) + const uint8_t *haystack, uint32_t haystack_len) { uint16_t matcher = ctx->matcher; return spm_table[matcher].Scan(ctx, thread_ctx, haystack, haystack_len); diff --git a/src/util-spm.h b/src/util-spm.h index a29da29d32..2f3b60fe7e 100644 --- a/src/util-spm.h +++ b/src/util-spm.h @@ -68,7 +68,7 @@ typedef struct SpmTableElmt_ { SpmGlobalThreadCtx *g_thread_ctx); void (*DestroyCtx)(SpmCtx *); uint8_t *(*Scan)(const SpmCtx *ctx, SpmThreadCtx *thread_ctx, - const uint8_t *haystack, uint16_t haystack_len); + const uint8_t *haystack, uint32_t haystack_len); } SpmTableElmt; SpmTableElmt spm_table[SPM_TABLE_SIZE]; @@ -89,7 +89,7 @@ SpmCtx *SpmInitCtx(const uint8_t *needle, uint16_t needle_len, int nocase, void SpmDestroyCtx(SpmCtx *ctx); uint8_t *SpmScan(const SpmCtx *ctx, SpmThreadCtx *thread_ctx, - const uint8_t *haystack, uint16_t haystack_len); + const uint8_t *haystack, uint32_t haystack_len); /** Default algorithm to use: Boyer Moore */ uint8_t *Bs2bmSearch(const uint8_t *text, uint32_t textlen, const uint8_t *needle, uint16_t needlelen);