]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
dcerpc: config limit maximum number of live transactions 8459/head
authorPhilippe Antoine <pantoine@oisf.net>
Tue, 10 Jan 2023 10:08:36 +0000 (11:08 +0100)
committerVictor Julien <vjulien@oisf.net>
Thu, 26 Jan 2023 06:01:34 +0000 (07:01 +0100)
As is done for other protocols

Ticket: #5779

doc/userguide/configuration/suricata-yaml.rst
rust/src/dcerpc/dcerpc.rs
suricata.yaml.in

index 84b953f56415a57365ee18cc8077eb5ca1eba1e0..fa96d04b54774ea7e2628a3a3087e4d7fed2a8be 100644 (file)
@@ -1722,7 +1722,7 @@ incompatible with ``decode-mime``. If both are enabled,
 Maximum transactions
 ~~~~~~~~~~~~~~~~~~~~
 
-MQTT, FTP, PostgreSQL, SMB and NFS have each a `max-tx` parameter that can be customized.
+MQTT, FTP, PostgreSQL, SMB, DCERPC and NFS have each a `max-tx` parameter that can be customized.
 `max-tx` refers to the maximum number of live transactions for each flow.
 An app-layer event `protocol.too_many_transactions` is triggered when this value is reached.
 The point of this parameter is to find a balance between the completeness of analysis
index 16227063731dc65b782816f1895d89772cd5f64a..5cefc2c34702a9a7b8e7954eca56ad578fd1e396 100644 (file)
@@ -25,6 +25,7 @@ use std;
 use std::cmp;
 use std::ffi::CString;
 use std::collections::VecDeque;
+use crate::conf::conf_get;
 
 // Constant DCERPC UDP Header length
 pub const DCERPC_HDR_LEN: u16 = 16;
@@ -110,6 +111,8 @@ pub const DCERPC_TYPE_ORPHANED: u8 = 19;
 pub const DCERPC_TYPE_RTS: u8 = 20;
 pub const DCERPC_TYPE_UNKNOWN: u8 = 99;
 
+static mut DCERPC_MAX_TX: usize = 1024;
+
 pub static mut ALPROTO_DCERPC: AppProto = ALPROTO_UNKNOWN;
 
 pub fn dcerpc_type_string(t: u8) -> String {
@@ -305,6 +308,7 @@ pub struct DCERPCState {
     pub bind: Option<DCERPCBind>,
     pub bindack: Option<DCERPCBindAck>,
     pub transactions: VecDeque<DCERPCTransaction>,
+    tx_index_completed: usize,
     pub buffer_ts: Vec<u8>,
     pub buffer_tc: Vec<u8>,
     pub pad: u8,
@@ -352,6 +356,18 @@ impl DCERPCState {
         self.tx_id += 1;
         tx.req_done = self.ts_ssn_trunc;
         tx.resp_done = self.tc_ssn_trunc;
+        if self.transactions.len() > unsafe { DCERPC_MAX_TX } {
+            let mut index = self.tx_index_completed;
+            for tx_old in &mut self.transactions.range_mut(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
     }
 
@@ -372,6 +388,7 @@ impl DCERPCState {
         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);
         }
     }
@@ -1397,6 +1414,13 @@ pub unsafe extern "C" fn rs_dcerpc_register_parser() {
         {
             let _ = AppLayerRegisterParser(&parser, alproto);
         }
+        if let Some(val) = conf_get("app-layer.protocols.dcerpc.max-tx") {
+            if let Ok(v) = val.parse::<usize>() {
+                DCERPC_MAX_TX = v;
+            } else {
+                SCLogError!("Invalid value for smb.max-tx");
+            }
+        }
         SCLogDebug!("Rust DCERPC parser registered.");
     } else {
         SCLogDebug!("Protocol detector and parser disabled for DCERPC.");
index 74a8b60dc0ec93adab7d75bdd39940cb7581e401..2d59bdae3a20aa23eeb84ab40fbd25fb4103041b 100644 (file)
@@ -900,6 +900,8 @@ app-layer:
       # max-tx: 1024
     dcerpc:
       enabled: yes
+      # Maximum number of live DCERPC transactions per flow
+      # max-tx: 1024
     ftp:
       enabled: yes
       # memcap: 64mb