From: Philippe Antoine Date: Mon, 28 Sep 2020 08:27:20 +0000 (+0200) Subject: applayer: fix a leak in protocol change X-Git-Tag: suricata-6.0.0~45 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=518e0e66cba5693e333e4dc3de6098d8eca6a57f;p=thirdparty%2Fsuricata.git applayer: fix a leak in protocol change TCPProtoDetect can either set f->alproto, change f->alstate and return error. When the original alstate gets freed, we shall set the pointer to NULL, as it can get reused. --- diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index 24fe493474..9188b4ca5d 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -1201,7 +1201,7 @@ int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow if (flags & STREAM_GAP) { if (!(p->option_flags & APP_LAYER_PARSER_OPT_ACCEPT_GAPS)) { SCLogDebug("app-layer parser does not accept gaps"); - if (f->alstate != NULL) { + if (f->alstate != NULL && !FlowChangeProto(f)) { AppLayerParserStreamTruncated(f->proto, alproto, f->alstate, flags); } diff --git a/src/app-layer.c b/src/app-layer.c index 60f2a278c1..c9cf0f4645 100644 --- a/src/app-layer.c +++ b/src/app-layer.c @@ -636,6 +636,7 @@ int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, /* rerun protocol detection */ int rd = TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags); if (f->alproto == ALPROTO_UNKNOWN) { + DEBUG_VALIDATE_BUG_ON(alstate_orig != f->alstate); // not enough data, revert AppLayerProtoDetectReset to rerun detection f->alparser = alparser; f->alproto = f->alproto_orig; @@ -644,10 +645,13 @@ int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, } else { FlowUnsetChangeProtoFlag(f); AppLayerParserStateProtoCleanup(f->protomap, f->alproto_orig, alstate_orig, alparser); + if (alstate_orig == f->alstate) { + // we just freed it + f->alstate = NULL; + } } if (rd != 0) { SCLogDebug("proto detect failure"); - f->alstate = NULL; goto failure; } SCLogDebug("protocol change, old %s, new %s",