]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
applayer: fix a leak in protocol change
authorPhilippe Antoine <contact@catenacyber.fr>
Wed, 9 Sep 2020 08:09:33 +0000 (10:09 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 7 Oct 2020 16:41:09 +0000 (18:41 +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 dc3d13be86b92651b6fc901a91aecf5ff9d1d45f..4d0befb9ebaa0d41cefd99b8f76bb3e23d017b9f 100644 (file)
@@ -1226,7 +1226,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 7e52237cd53c4b9164dabbc53cd50ca2b6e78212..25fbea68237097936306a9459475d5e73934038c 100644 (file)
@@ -635,6 +635,7 @@ int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
         int rd = TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags);
         if (f->alproto == ALPROTO_UNKNOWN) {
             // not enough data, revert AppLayerProtoDetectReset to rerun detection
+            DEBUG_VALIDATE_BUG_ON(alstate_orig != f->alstate);
             f->alparser = alparser;
             f->alstate = alstate_orig;
             f->alproto = f->alproto_orig;
@@ -643,6 +644,10 @@ 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");