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-8.0.0-beta1~309 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d8ddef4c1485004cfb24d0e4b1c490f185bedc92;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 --- diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index 190aa4ea15..d88cab6b48 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -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, 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 c4d742f8b3..8350e0cec0 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -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))) { diff --git a/src/app-layer-smb.c b/src/app-layer-smb.c index 2cc67f9146..87ab1affb2 100644 --- a/src/app-layer-smb.c +++ b/src/app-layer-smb.c @@ -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" \