From 4cd06d224714a3735d0b99b6808e521df3ec2e8c Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 8 Jun 2023 14:25:01 +0200 Subject: [PATCH] dcerpc: maximum number of live transactions also for UDP Ticket: #6129 Avoids that quadratic complexity gets too bad (cherry picked from commit d40dca5e55286c57e9a83018975022c4f08bf6d1) --- rust/src/dcerpc/dcerpc.rs | 2 ++ rust/src/dcerpc/dcerpc_udp.rs | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/rust/src/dcerpc/dcerpc.rs b/rust/src/dcerpc/dcerpc.rs index b874954ee2..e922fb3ac0 100644 --- a/rust/src/dcerpc/dcerpc.rs +++ b/rust/src/dcerpc/dcerpc.rs @@ -109,6 +109,8 @@ pub const DCERPC_TYPE_ORPHANED: u8 = 19; pub const DCERPC_TYPE_RTS: u8 = 20; pub const DCERPC_TYPE_UNKNOWN: u8 = 99; +pub(super) static mut DCERPC_MAX_TX: usize = 1024; + pub fn dcerpc_type_string(t: u8) -> String { match t { DCERPC_TYPE_REQUEST => "REQUEST", diff --git a/rust/src/dcerpc/dcerpc_udp.rs b/rust/src/dcerpc/dcerpc_udp.rs index 3ed1801b2b..e39c5f14a0 100644 --- a/rust/src/dcerpc/dcerpc_udp.rs +++ b/rust/src/dcerpc/dcerpc_udp.rs @@ -20,7 +20,7 @@ use std::mem::transmute; use crate::applayer::{AppLayerResult, AppLayerTxData}; use crate::core; use crate::dcerpc::dcerpc::{ - DCERPCTransaction, DCERPC_TYPE_REQUEST, DCERPC_TYPE_RESPONSE, PFCL1_FRAG, PFCL1_LASTFRAG, + DCERPCTransaction, DCERPC_MAX_TX, DCERPC_TYPE_REQUEST, DCERPC_TYPE_RESPONSE, PFCL1_FRAG, PFCL1_LASTFRAG, }; use std::collections::VecDeque; use crate::dcerpc::parser; @@ -55,12 +55,14 @@ pub struct DCERPCHdrUdp { pub struct DCERPCUDPState { pub tx_id: u64, pub transactions: VecDeque, + tx_index_completed: usize, } impl DCERPCUDPState { pub fn new() -> DCERPCUDPState { return DCERPCUDPState { tx_id: 0, + tx_index_completed: 0, transactions: VecDeque::new(), }; } @@ -72,6 +74,18 @@ impl DCERPCUDPState { tx.activityuuid = hdr.activityuuid.to_vec(); tx.seqnum = hdr.seqnum; self.tx_id += 1; + if self.transactions.len() > unsafe { DCERPC_MAX_TX } { + let mut index = self.tx_index_completed; + for tx_old in &mut self.transactions.iter_mut().skip(self.tx_index_completed) { + index += 1; + if !tx_old.req_done || !tx_old.resp_done { + tx_old.req_done = true; + tx_old.resp_done = true; + break; + } + } + self.tx_index_completed = index; + } tx } @@ -92,6 +106,7 @@ impl DCERPCUDPState { if found { SCLogDebug!("freeing TX with ID {} TX.ID {} at index {} left: {} max id: {}", tx_id, tx_id+1, index, self.transactions.len(), self.tx_id); + self.tx_index_completed = 0; self.transactions.remove(index); } } -- 2.47.2