]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
smb2: add options for max read/write size
authorVictor Julien <vjulien@oisf.net>
Mon, 18 Apr 2022 19:47:39 +0000 (21:47 +0200)
committerVictor Julien <vjulien@oisf.net>
Wed, 20 Apr 2022 18:46:03 +0000 (20:46 +0200)
Add options for the max read/write size accepted by the parser.

(cherry picked from commit 5bcc4162f7051194d228ba6c58a665d71c0c047c)

rust/src/smb/smb.rs
rust/src/smb/smb2.rs
src/app-layer-smb.c

index 73bd3655a0b285c9f628b4140da594c6290ef80a..8bbc8f355884ce1ca73b96582bd44c60769c1ef8 100644 (file)
@@ -51,6 +51,9 @@ use crate::smb::events::*;
 use crate::smb::files::*;
 use crate::smb::smb2_ioctl::*;
 
+pub static mut SMB_CFG_MAX_READ_SIZE: u32 = 0;
+pub static mut SMB_CFG_MAX_WRITE_SIZE: u32 = 0;
+
 pub static mut SURICATA_SMB_FILE_CONFIG: Option<&'static SuricataFileContext> = None;
 
 #[no_mangle]
@@ -2263,3 +2266,10 @@ pub extern "C" fn rs_smb_state_get_event_info(event_name: *const std::os::raw::c
     }
     0
 }
+
+#[no_mangle]
+pub unsafe extern "C" fn rs_smb_set_conf_val(max_read_size: u32, max_write_size: u32)
+{
+    SMB_CFG_MAX_READ_SIZE = max_read_size;
+    SMB_CFG_MAX_WRITE_SIZE = max_write_size;
+}
index cdf9a449542f867c8dda8da287be92aa516157f2..216a8681fa271e8b6c0cc2ef5deebd4b04e6b0f4 100644 (file)
@@ -128,7 +128,9 @@ pub fn smb2_read_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
                 return;
             }
 
-            if state.max_read_size > 0 && rd.len > state.max_read_size {
+            if (state.max_read_size != 0 && rd.len > state.max_read_size) ||
+               (unsafe { SMB_CFG_MAX_READ_SIZE != 0 && SMB_CFG_MAX_READ_SIZE < rd.len })
+            {
                 state.set_event(SMBEvent::ReadResponseTooLarge);
                 state.set_skip(STREAM_TOCLIENT, rd.len, rd.data.len() as u32);
                 return;
@@ -253,7 +255,8 @@ pub fn smb2_write_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
     }
     match parse_smb2_request_write(r.data) {
         Ok((_, wr)) => {
-            if state.max_read_size != 0 && wr.wr_len > state.max_write_size {
+            if (state.max_write_size != 0 && wr.wr_len > state.max_write_size) ||
+               (unsafe { SMB_CFG_MAX_WRITE_SIZE != 0 && SMB_CFG_MAX_WRITE_SIZE < wr.wr_len }) {
                 state.set_event(SMBEvent::WriteRequestTooLarge);
                 state.set_skip(STREAM_TOSERVER, wr.wr_len, wr.data.len() as u32);
                 return;
@@ -471,7 +474,8 @@ pub fn smb2_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
         SMB2_COMMAND_READ => {
             match parse_smb2_request_read(r.data) {
                 Ok((_, rd)) => {
-                    if state.max_read_size != 0 && rd.rd_len > state.max_read_size {
+                    if (state.max_read_size != 0 && rd.rd_len > state.max_read_size) ||
+                        (unsafe { SMB_CFG_MAX_READ_SIZE != 0 && SMB_CFG_MAX_READ_SIZE < rd.rd_len }) {
                         events.push(SMBEvent::ReadRequestTooLarge);
                     } else {
                         SCLogDebug!("SMBv2 READ: GUID {:?} requesting {} bytes at offset {}",
index 0b7f3bcab3ec5a4075fceac6dc0490e08b9963fd..8db224a874ea1d9ced1349476ec36f308910aa5e 100644 (file)
@@ -261,7 +261,8 @@ static uint32_t stream_depth = SMB_CONFIG_DEFAULT_STREAM_DEPTH;
 void RegisterSMBParsers(void)
 {
     const char *proto_name = "smb";
-
+    uint32_t max_read_size = 0;
+    uint32_t max_write_size = 0;
     /** SMB */
     if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) {
         AppLayerProtoDetectRegisterProtocol(ALPROTO_SMB, proto_name);
@@ -342,8 +343,31 @@ void RegisterSMBParsers(void)
             }
         }
         SCLogConfig("SMB stream depth: %u", stream_depth);
-
         AppLayerParserSetStreamDepth(IPPROTO_TCP, ALPROTO_SMB, stream_depth);
+
+        ConfNode *r = ConfGetNode("app-layer.protocols.smb.max-read-size");
+        if (r != NULL) {
+            uint32_t value;
+            if (ParseSizeStringU32(r->val, &value) < 0) {
+                SCLogError(SC_ERR_SMB_CONFIG, "invalid value for max-read-size %s", r->val);
+            } else {
+                max_read_size = value;
+            }
+        }
+        SCLogConfig("SMB max-read-size: %u", max_read_size);
+
+        ConfNode *w = ConfGetNode("app-layer.protocols.smb.max-write-size");
+        if (w != NULL) {
+            uint32_t value;
+            if (ParseSizeStringU32(w->val, &value) < 0) {
+                SCLogError(SC_ERR_SMB_CONFIG, "invalid value for max-write-size %s", w->val);
+            } else {
+                max_write_size = value;
+            }
+        }
+        SCLogConfig("SMB max-write-size: %u", max_write_size);
+
+        rs_smb_set_conf_val(max_read_size, max_write_size);
     } else {
         SCLogConfig("Parsed disabled for %s protocol. Protocol detection"
                   "still on.", proto_name);