diff --git a/src/datasets-context-json.c b/src/datasets-context-json.c index 3d1ac1fc07ab..36675ff74c5c 100644 --- a/src/datasets-context-json.c +++ b/src/datasets-context-json.c @@ -895,6 +895,12 @@ int DatajsonAddSerialized(Dataset *set, const char *value, const char *json) int ret = -1; switch (set->type) { case DATASET_TYPE_STRING: { + if (strlen(value) > UINT16_MAX) { + // size check before stack allocation + // should never happen as unix socket callers limits it to 4k + SCFree(jvalue.value); + return -1; + } uint32_t decoded_size = SCBase64DecodeBufferSize((uint32_t)strlen(value)); uint8_t decoded[decoded_size]; uint32_t num_decoded = SCBase64Decode( diff --git a/src/detect-engine-analyzer.c b/src/detect-engine-analyzer.c index dc5cf98bb9f9..1eb2f9f0ebea 100644 --- a/src/detect-engine-analyzer.c +++ b/src/detect-engine-analyzer.c @@ -1560,8 +1560,14 @@ void DumpPatterns(DetectEngineCtx *de_ctx) return; SCJsonBuilder *root_jb = SCJbNewObject(); - SCJsonBuilder *arrays[de_ctx->buffer_type_id]; - memset(&arrays, 0, sizeof(SCJsonBuilder *) * de_ctx->buffer_type_id); + if (root_jb == NULL) { + return; + } + SCJsonBuilder **arrays = SCCalloc(de_ctx->buffer_type_id, sizeof(SCJsonBuilder *)); + if (arrays == NULL) { + SCJbFree(root_jb); + return; + } SCJbOpenArray(root_jb, "buffers"); @@ -1629,6 +1635,7 @@ void DumpPatterns(DetectEngineCtx *de_ctx) } SCMutexUnlock(&g_rules_analyzer_write_m); SCJbFree(root_jb); + SCFree(arrays); HashListTableFree(de_ctx->pattern_hash_table); de_ctx->pattern_hash_table = NULL; diff --git a/src/detect-engine-build.c b/src/detect-engine-build.c index 4c6278bce459..d0aeb8c120fa 100644 --- a/src/detect-engine-build.c +++ b/src/detect-engine-build.c @@ -602,6 +602,13 @@ static bool RuleMpmIsNegated(const Signature *s) return (cd->flags & DETECT_CONTENT_NEGATED) ? true : false; } +typedef struct MpmStat { + uint32_t total; + uint32_t cnt; + uint32_t min; + uint32_t max; +} MpmStat; + static SCJsonBuilder *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, const SigGroupHead *sgh, const int add_rules, const int add_mpm_stats) { @@ -620,13 +627,12 @@ static SCJsonBuilder *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, int max_buffer_type_id = de_ctx->buffer_type_id; - struct { - uint32_t total; - uint32_t cnt; - uint32_t min; - uint32_t max; - } mpm_stats[max_buffer_type_id]; - memset(mpm_stats, 0x00, sizeof(mpm_stats)); + MpmStat *mpm_stats = NULL; + if (add_mpm_stats) { + mpm_stats = SCCalloc(max_buffer_type_id, sizeof(MpmStat)); + if (mpm_stats == NULL) + return NULL; + } uint32_t alstats[g_alproto_max]; memset(alstats, 0, g_alproto_max * sizeof(uint32_t)); @@ -636,12 +642,16 @@ static SCJsonBuilder *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, memset(alproto_mpm_bufs, 0, sizeof(alproto_mpm_bufs)); DEBUG_VALIDATE_BUG_ON(sgh->init == NULL); - if (sgh->init == NULL) + if (sgh->init == NULL) { + SCFree(mpm_stats); return NULL; + } SCJsonBuilder *js = SCJbNewObject(); - if (unlikely(js == NULL)) + if (unlikely(js == NULL)) { + SCFree(mpm_stats); return NULL; + } SCJbSetUint(js, "id", sgh->id); @@ -732,13 +742,14 @@ static SCJsonBuilder *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, mpms_max = w; BUG_ON(mpm_list >= max_buffer_type_id); - mpm_stats[mpm_list].total += w; - mpm_stats[mpm_list].cnt++; - if (mpm_stats[mpm_list].min == 0 || w < mpm_stats[mpm_list].min) - mpm_stats[mpm_list].min = w; - if (w > mpm_stats[mpm_list].max) - mpm_stats[mpm_list].max = w; - + if (mpm_stats != NULL) { + mpm_stats[mpm_list].total += w; + mpm_stats[mpm_list].cnt++; + if (mpm_stats[mpm_list].min == 0 || w < mpm_stats[mpm_list].min) + mpm_stats[mpm_list].min = w; + if (w > mpm_stats[mpm_list].max) + mpm_stats[mpm_list].max = w; + } mpm_cnt++; if (w < 10) { @@ -863,6 +874,7 @@ static SCJsonBuilder *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, SCJbSetUint(js, "score", sgh->init->score); SCJbClose(js); + SCFree(mpm_stats); return js; } diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index c1af73c2fdd5..243d18c4c23a 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -1149,6 +1149,7 @@ void RetrieveFPForSig(const DetectEngineCtx *de_ctx, Signature *s) return; const int nlists = s->init_data->max_content_list_id + 1; + DEBUG_VALIDATE_BUG_ON(nlists > UINT16_MAX); int pos_sm_list[nlists]; int neg_sm_list[nlists]; memset(pos_sm_list, 0, nlists * sizeof(int)); @@ -1522,18 +1523,23 @@ static const DetectBufferMpmRegistry *GetByMpmStore( void MpmStoreReportStats(const DetectEngineCtx *de_ctx) { HashListTableBucket *htb = NULL; + uint32_t *appstats = NULL; + uint32_t *pktstats = NULL; + uint32_t *framestats = NULL; uint32_t stats[MPMB_MAX] = {0}; - DEBUG_VALIDATE_BUG_ON(de_ctx->buffer_type_id > UINT16_MAX); - int app_mpms_cnt = de_ctx->buffer_type_id; - uint32_t appstats[app_mpms_cnt + 1]; // +1 to silence scan-build - memset(&appstats, 0x00, sizeof(appstats)); - int pkt_mpms_cnt = de_ctx->buffer_type_id; - uint32_t pktstats[pkt_mpms_cnt + 1]; // +1 to silence scan-build - memset(&pktstats, 0x00, sizeof(pktstats)); - int frame_mpms_cnt = de_ctx->buffer_type_id; - uint32_t framestats[frame_mpms_cnt + 1]; // +1 to silence scan-build - memset(&framestats, 0x00, sizeof(framestats)); + appstats = SCCalloc(de_ctx->buffer_type_id, sizeof(uint32_t)); + if (appstats == NULL) { + goto end; + } + pktstats = SCCalloc(de_ctx->buffer_type_id, sizeof(uint32_t)); + if (pktstats == NULL) { + goto end; + } + framestats = SCCalloc(de_ctx->buffer_type_id, sizeof(uint32_t)); + if (framestats == NULL) { + goto end; + } for (htb = HashListTableGetListHead(de_ctx->mpm_hash_table); htb != NULL; @@ -1609,6 +1615,13 @@ void MpmStoreReportStats(const DetectEngineCtx *de_ctx) um = um->next; } } +end: + if (appstats) + SCFree(appstats); + if (pktstats) + SCFree(pktstats); + if (framestats) + SCFree(framestats); } /** @@ -1733,11 +1746,12 @@ MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh, uint32_t cnt = 0; int direction = 0; uint32_t max_sid = DetectEngineGetMaxSigId(de_ctx) / 8 + 1; - uint8_t sids_array[max_sid]; - memset(sids_array, 0x00, max_sid); int sgh_mpm_context = 0; int sm_list = DETECT_SM_LIST_PMATCH; - + uint8_t *sids_array = SCCalloc(1, max_sid); + if (sids_array == NULL) { + return NULL; + } switch (buf) { case MPMB_TCP_PKT_TS: case MPMB_TCP_PKT_TC: @@ -1826,8 +1840,10 @@ MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh, } } - if (cnt == 0) + if (cnt == 0) { + SCFree(sids_array); return NULL; + } MpmStore lookup = { sids_array, max_sid, direction, buf, sm_list, 0, 0, NULL }; @@ -1839,6 +1855,7 @@ MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh, uint8_t *sids = SCCalloc(1, max_sid); if (sids == NULL) { SCFree(copy); + SCFree(sids_array); return NULL; } @@ -1852,8 +1869,10 @@ MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmStoreSetup(de_ctx, copy); MpmStoreAdd(de_ctx, copy); + SCFree(sids_array); return copy; } else { + SCFree(sids_array); return result; } } @@ -2069,12 +2088,12 @@ static void PrepareMpms(DetectEngineCtx *de_ctx, SigGroupHead *sh) const int max_buffer_id = de_ctx->buffer_type_id + 1; const uint32_t max_sid = DetectEngineGetMaxSigId(de_ctx) / 8 + 1; - AppProto engines[max_buffer_id][g_alproto_max]; - memset(engines, 0, sizeof(engines)); - int engines_idx[max_buffer_id]; - memset(engines_idx, 0, sizeof(engines_idx)); - int types[max_buffer_id]; - memset(types, 0, sizeof(types)); + AppProto *engines = SCCalloc(max_buffer_id * g_alproto_max, sizeof(AppProto)); + BUG_ON(engines == NULL); + int *engines_idx = SCCalloc(max_buffer_id, sizeof(int)); + BUG_ON(engines_idx == NULL); + int *types = SCCalloc(max_buffer_id, sizeof(int)); + BUG_ON(types == NULL); /* flag the list+directions we have engines for as active */ for (DetectBufferMpmRegistry *a = de_ctx->pkt_mpms_list; a != NULL; a = a->next) { @@ -2097,7 +2116,7 @@ static void PrepareMpms(DetectEngineCtx *de_ctx, SigGroupHead *sh) const bool add_tc = ((a->direction == SIG_FLAG_TOCLIENT) && SGH_DIRECTION_TC(sh)); if (add_ts || add_tc) { types[a->sm_list] = a->type; - engines[a->sm_list][engines_idx[a->sm_list]++] = a->frame_v1.alproto; + engines[g_alproto_max * a->sm_list + engines_idx[a->sm_list]++] = a->frame_v1.alproto; DetectBufferInstance lookup = { .list = a->sm_list, .alproto = a->frame_v1.alproto }; DetectBufferInstance *instance = HashListTableLookup(bufs, &lookup, 0); @@ -2117,7 +2136,7 @@ static void PrepareMpms(DetectEngineCtx *de_ctx, SigGroupHead *sh) const bool add_tc = ((a->direction == SIG_FLAG_TOCLIENT) && SGH_DIRECTION_TC(sh)); if (add_ts || add_tc) { types[a->sm_list] = a->type; - engines[a->sm_list][engines_idx[a->sm_list]++] = a->app_v2.alproto; + engines[g_alproto_max * a->sm_list + engines_idx[a->sm_list]++] = a->app_v2.alproto; DetectBufferInstance lookup = { .list = a->sm_list, .alproto = a->app_v2.alproto }; DetectBufferInstance *instance = HashListTableLookup(bufs, &lookup, 0); @@ -2150,7 +2169,7 @@ static void PrepareMpms(DetectEngineCtx *de_ctx, SigGroupHead *sh) case DETECT_BUFFER_MPM_TYPE_FRAME: case DETECT_BUFFER_MPM_TYPE_APP: { for (int e = 0; e < engines_idx[list]; e++) { - const AppProto alproto = engines[list][e]; + const AppProto alproto = engines[list * g_alproto_max + e]; if (!(AppProtoEquals(s->alproto, alproto) || s->alproto == 0)) continue; @@ -2311,6 +2330,9 @@ static void PrepareMpms(DetectEngineCtx *de_ctx, SigGroupHead *sh) } } HashListTableFree(bufs); + SCFree(engines); + SCFree(engines_idx); + SCFree(types); } /** \brief Prepare the pattern matcher ctx in a sig group head.