]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
applayer: fix a leak in protocol change 5452/head
authorPhilippe Antoine <contact@catenacyber.fr>
Mon, 28 Sep 2020 08:27:20 +0000 (10:27 +0200)
committerVictor Julien <victor@inliniac.net>
Mon, 28 Sep 2020 09:33:46 +0000 (11:33 +0200)
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.

src/app-layer-parser.c
src/app-layer.c

index 24fe493474f2ae6f58243d091e0353f4662075c6..9188b4ca5df4d6f9650f9d56f67926e7cf6a08a6 100644 (file)
@@ -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);
             }
index 60f2a278c14b866be9fbda5a63d4ca7d044ab640..c9cf0f4645739695e04a83dca558b519f6fe4922 100644 (file)
@@ -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",