]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: delay tx cleanup in some edge case 12730/head
authorPhilippe Antoine <pantoine@oisf.net>
Tue, 25 Feb 2025 09:54:13 +0000 (10:54 +0100)
committerVictor Julien <victor@inliniac.net>
Fri, 7 Mar 2025 06:01:56 +0000 (07:01 +0100)
Ticket: 7552

f->sgh_toserver may be NULL but because FLOW_SGH_TOSERVER is unset
and thus, we want to delay cleanup until detection has really been
run with the right signature group head.

This may happen for a rule using
`alert tcp any any -> any any` and
a app-layer keyword to client
with a app-layer supporting both udp and tcp
with stream.midstream=true
and with the first packet of a flow being a server response

In this case, we swap the flow and reset its signature group heads

src/app-layer-htp.c
src/app-layer-ike.c
src/app-layer-parser.c
src/app-layer-smb.c

index 190aa4ea15688b7857a101eb29075e8c0c8c68dd..d88cab6b487aa2727839adb5507257b23954788e 100644 (file)
@@ -5628,6 +5628,7 @@ static int HTPParserTest25(void)
     f->protoctx = &ssn;
     f->proto = IPPROTO_TCP;
     f->alproto = ALPROTO_HTTP1;
+    f->flags |= FLOW_SGH_TOCLIENT | FLOW_SGH_TOSERVER;
 
     const char *str = "GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
     int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START,
index 9a66904ab0a3f8d4702c49f55084492d1973784e..fa8c33cc8094e52a2a97ad7072fcab49b6c78635 100644 (file)
@@ -66,6 +66,7 @@ static int IkeParserTest(void)
     f.proto = IPPROTO_UDP;
     f.protomap = FlowGetProtoMapping(f.proto);
     f.alproto = ALPROTO_IKE;
+    f.flags |= FLOW_SGH_TOCLIENT | FLOW_SGH_TOSERVER;
 
     StreamTcpInitConfig(true);
 
index c4d742f8b3d8ffaf94aa4f4d84c3e231036b5a9e..8350e0cec0037f9d24693851468297af9b3d8e1b 100644 (file)
@@ -958,7 +958,8 @@ void AppLayerParserTransactionsCleanup(Flow *f, const uint8_t pkt_dir)
         }
 
         if (txd && has_tx_detect_flags) {
-            if (!IS_DISRUPTED(ts_disrupt_flags) && f->sgh_toserver != NULL) {
+            if (!IS_DISRUPTED(ts_disrupt_flags) &&
+                    (f->sgh_toserver != NULL || (f->flags & FLOW_SGH_TOSERVER) == 0)) {
                 uint64_t detect_flags_ts = AppLayerParserGetTxDetectFlags(txd, STREAM_TOSERVER);
                 if (!(detect_flags_ts &
                             (APP_LAYER_TX_INSPECTED_FLAG | APP_LAYER_TX_SKIP_INSPECT_FLAG))) {
@@ -967,7 +968,8 @@ void AppLayerParserTransactionsCleanup(Flow *f, const uint8_t pkt_dir)
                     tx_skipped = true;
                 }
             }
-            if (!IS_DISRUPTED(tc_disrupt_flags) && f->sgh_toclient != NULL) {
+            if (!IS_DISRUPTED(tc_disrupt_flags) &&
+                    (f->sgh_toclient != NULL || (f->flags & FLOW_SGH_TOCLIENT) == 0)) {
                 uint64_t detect_flags_tc = AppLayerParserGetTxDetectFlags(txd, STREAM_TOCLIENT);
                 if (!(detect_flags_tc &
                             (APP_LAYER_TX_INSPECTED_FLAG | APP_LAYER_TX_SKIP_INSPECT_FLAG))) {
index 2cc67f9146afc44cd241d0c69a83ace84d9ffe3b..87ab1affb268c4e08046364b242e593c492e39e0 100644 (file)
@@ -72,6 +72,7 @@ static int SMBParserTxCleanupTest(void)
     f->protoctx = &ssn;
     f->proto = IPPROTO_TCP;
     f->alproto = ALPROTO_SMB;
+    f->flags |= FLOW_SGH_TOCLIENT | FLOW_SGH_TOSERVER;
 
     char req_str[] ="\x00\x00\x00\x79\xfe\x53\x4d\x42\x40\x00\x01\x00\x00\x00\x00\x00" \
                      "\x05\x00\xe0\x1e\x10\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00" \