From: Philippe Antoine Date: Tue, 25 Feb 2025 09:54:13 +0000 (+0100) Subject: detect: delay tx cleanup in some edge case X-Git-Tag: suricata-7.0.9~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b30f286a6e9520c9ce32a79454066cee0b57f24e;p=thirdparty%2Fsuricata.git detect: delay tx cleanup in some edge case 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 (cherry picked from commit d8ddef4c1485004cfb24d0e4b1c490f185bedc92) Additional fix in rfb unit test which moved to SV in suricata 8 --- diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index 16f832fd5d..6df6c3270f 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -6829,6 +6829,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, diff --git a/src/app-layer-ike.c b/src/app-layer-ike.c index 9a66904ab0..fa8c33cc80 100644 --- a/src/app-layer-ike.c +++ b/src/app-layer-ike.c @@ -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); diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index 5d33dca714..b3b9678525 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -999,7 +999,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))) { @@ -1008,7 +1009,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))) { diff --git a/src/app-layer-rfb.c b/src/app-layer-rfb.c index 829e918adc..97a2af3151 100644 --- a/src/app-layer-rfb.c +++ b/src/app-layer-rfb.c @@ -83,6 +83,7 @@ static int RFBParserTest(void) f->protoctx = &ssn; f->proto = IPPROTO_TCP; f->alproto = ALPROTO_RFB; + f->flags |= FLOW_SGH_TOCLIENT | FLOW_SGH_TOSERVER; static const unsigned char rfb_version_str[12] = { 0x52, 0x46, 0x42, 0x20, 0x30, 0x30, 0x33, 0x2e, 0x30, 0x30, 0x37, 0x0a diff --git a/src/app-layer-smb.c b/src/app-layer-smb.c index 0c6102e83e..24ae88c81a 100644 --- a/src/app-layer-smb.c +++ b/src/app-layer-smb.c @@ -74,6 +74,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" \