diff --git a/src/app-layer-detect-proto.c b/src/app-layer-detect-proto.c index a64ffe96ba..767350628d 100644 --- a/src/app-layer-detect-proto.c +++ b/src/app-layer-detect-proto.c @@ -157,12 +157,14 @@ typedef struct AppLayerProtoDetectCtx_ { * ipproto. It should be allocated to contain ALPROTO_MAX * protocols. */ const char **alproto_names; + size_t alproto_names_len; /* Protocol expectations, like ftp-data on tcp. * It should be allocated to contain ALPROTO_MAX * app-layer protocols. For each protocol, an iptype * is referenced (or 0 if there is no expectation). */ uint8_t *expectation_proto; + size_t expectation_proto_len; } AppLayerProtoDetectCtx; typedef struct AppLayerProtoDetectAliases_ { @@ -1704,11 +1706,13 @@ int AppLayerProtoDetectSetup(void) if (unlikely(alpd_ctx.alproto_names == NULL)) { FatalError("Unable to alloc alproto_names."); } + alpd_ctx.alproto_names_len = g_alproto_max; // to realloc when dynamic protos are added alpd_ctx.expectation_proto = SCCalloc(g_alproto_max, sizeof(uint8_t)); if (unlikely(alpd_ctx.expectation_proto == NULL)) { FatalError("Unable to alloc expectation_proto."); } + alpd_ctx.expectation_proto_len = g_alproto_max; AppLayerExpectationSetup(); SCReturnInt(0); @@ -1742,8 +1746,10 @@ int AppLayerProtoDetectDeSetup(void) SCFree(alpd_ctx.alproto_names); alpd_ctx.alproto_names = NULL; + alpd_ctx.alproto_names_len = 0; SCFree(alpd_ctx.expectation_proto); alpd_ctx.expectation_proto = NULL; + alpd_ctx.expectation_proto_len = 0; SpmDestroyGlobalThreadCtx(alpd_ctx.spm_global_thread_ctx); @@ -1758,7 +1764,16 @@ void AppLayerProtoDetectRegisterProtocol(AppProto alproto, const char *alproto_n { SCEnter(); - // should have just been realloced when dynamic protos is added + if (alpd_ctx.alproto_names_len <= alproto && alproto < g_alproto_max) { + void *tmp = SCRealloc(alpd_ctx.alproto_names, sizeof(char *) * g_alproto_max); + if (unlikely(tmp == NULL)) { + FatalError("Unable to realloc alproto_names."); + } + alpd_ctx.alproto_names = tmp; + memset(&alpd_ctx.alproto_names[alpd_ctx.alproto_names_len], 0, + sizeof(char *) * (g_alproto_max - alpd_ctx.alproto_names_len)); + alpd_ctx.alproto_names_len = g_alproto_max; + } if (alpd_ctx.alproto_names[alproto] == NULL) alpd_ctx.alproto_names[alproto] = alproto_name; @@ -2111,6 +2126,9 @@ void AppLayerProtoDetectSupportedAppProtocols(AppProto *alprotos) static void AppLayerProtoDetectPEGetIpprotos(AppProto alproto, uint8_t *ipprotos) { + if (alproto >= alpd_ctx.expectation_proto_len) { + return; + } if (alpd_ctx.expectation_proto[alproto] == IPPROTO_TCP) { ipprotos[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8); } diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index 0237bbb7a0..6f36def8fe 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -124,6 +124,7 @@ typedef struct AppLayerParserProtoCtx_ typedef struct AppLayerParserCtx_ { AppLayerParserProtoCtx (*ctxs)[FLOW_PROTO_MAX]; + size_t ctxs_len; } AppLayerParserCtx; struct AppLayerParserState_ { @@ -259,6 +260,7 @@ int AppLayerParserSetup(void) if (unlikely(alp_ctx.ctxs == NULL)) { FatalError("Unable to alloc alp_ctx.ctxs."); } + alp_ctx.ctxs_len = g_alproto_max; SCReturnInt(0); } @@ -431,6 +433,20 @@ void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto, { SCEnter(); + if (alp_ctx.ctxs_len <= alproto && alproto < g_alproto_max) { + // Realloc now as AppLayerParserRegisterStateFuncs is called first + void *tmp = SCRealloc( + alp_ctx.ctxs, sizeof(AppLayerParserProtoCtx[FLOW_PROTO_MAX]) * g_alproto_max); + if (unlikely(tmp == NULL)) { + FatalError("Unable to realloc alp_ctx.ctxs."); + } + alp_ctx.ctxs = tmp; + memset(&alp_ctx.ctxs[alp_ctx.ctxs_len], 0, + sizeof(AppLayerParserProtoCtx[FLOW_PROTO_MAX]) * + (g_alproto_max - alp_ctx.ctxs_len)); + alp_ctx.ctxs_len = g_alproto_max; + } + alp_ctx.ctxs[alproto][FlowGetProtoMapping(ipproto)].StateAlloc = StateAlloc; alp_ctx.ctxs[alproto][FlowGetProtoMapping(ipproto)].StateFree = StateFree; @@ -1680,7 +1696,6 @@ bad: } #undef BOTH_SET #undef BOTH_SET_OR_BOTH_UNSET -#undef THREE_SET_OR_THREE_UNSET #undef THREE_SET static void ValidateParser(AppProto alproto)