]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
smb2: validate negotiate read/write max sizes
authorVictor Julien <vjulien@oisf.net>
Tue, 19 Apr 2022 06:13:48 +0000 (08:13 +0200)
committerVictor Julien <vjulien@oisf.net>
Wed, 20 Apr 2022 18:51:24 +0000 (20:51 +0200)
Raise event if they exceed the configured limit.

(cherry picked from commit fc9b65d8d3188c57016635aef8d7cdfe4552324e)

rust/src/smb/events.rs
rust/src/smb/smb.rs
rust/src/smb/smb2.rs

index 604804f285eed570f687278230e8f0ce1e0cceb0..f33e6932f7285c85c627b9ec0dae7128ec764955 100644 (file)
@@ -30,16 +30,20 @@ pub enum SMBEvent {
     FileOverlap = 7,
     RequestToClient = 8,
     ResponseToServer = 9,
+    /// Negotiated max sizes exceed our limit
+    NegotiateMaxReadSizeTooLarge = 10,
+    NegotiateMaxWriteSizeTooLarge = 11,
+
     /// READ request asking for more than `max_read_size`
-    ReadRequestTooLarge = 10,
+    ReadRequestTooLarge = 12,
     /// READ response bigger than `max_read_size`
-    ReadResponseTooLarge = 11,
-    ReadResponseQueueSizeExceeded = 12,
-    ReadResponseQueueCntExceeded = 13,
+    ReadResponseTooLarge = 13,
+    ReadResponseQueueSizeExceeded = 14,
+    ReadResponseQueueCntExceeded = 15,
     /// WRITE request for more than `max_write_size`
-    WriteRequestTooLarge = 14,
-    WriteQueueSizeExceeded = 15,
-    WriteQueueCntExceeded = 16,
+    WriteRequestTooLarge = 16,
+    WriteQueueSizeExceeded = 17,
+    WriteQueueCntExceeded = 18,
 }
 
 impl SMBEvent {
@@ -55,13 +59,15 @@ impl SMBEvent {
             7 => Some(SMBEvent::FileOverlap),
             8 => Some(SMBEvent::RequestToClient),
             9 => Some(SMBEvent::ResponseToServer),
-            10 => Some(SMBEvent::ReadRequestTooLarge),
-            11 => Some(SMBEvent::ReadResponseTooLarge),
-            12 => Some(SMBEvent::ReadResponseQueueSizeExceeded),
-            13 => Some(SMBEvent::ReadResponseQueueCntExceeded),
-            14 => Some(SMBEvent::WriteRequestTooLarge),
-            15 => Some(SMBEvent::WriteQueueSizeExceeded),
-            16 => Some(SMBEvent::WriteQueueCntExceeded),
+            10 => Some(SMBEvent::NegotiateMaxReadSizeTooLarge),
+            11 => Some(SMBEvent::NegotiateMaxWriteSizeTooLarge),
+            12 => Some(SMBEvent::ReadRequestTooLarge),
+            13 => Some(SMBEvent::ReadResponseTooLarge),
+            14 => Some(SMBEvent::ReadResponseQueueSizeExceeded),
+            15 => Some(SMBEvent::ReadResponseQueueCntExceeded),
+            16 => Some(SMBEvent::WriteRequestTooLarge),
+            17 => Some(SMBEvent::WriteQueueSizeExceeded),
+            18 => Some(SMBEvent::WriteQueueCntExceeded),
             _ => None,
         }
     }
@@ -80,6 +86,8 @@ pub fn smb_str_to_event(instr: &str) -> i32 {
         "file_overlap"                      => SMBEvent::FileOverlap as i32,
         "request_to_client"                 => SMBEvent::RequestToClient as i32,
         "response_to_server"                => SMBEvent::ResponseToServer as i32,
+        "negotiate_max_read_size_too_large"  => SMBEvent::NegotiateMaxReadSizeTooLarge as i32,
+        "negotiate_max_write_size_too_large" => SMBEvent::NegotiateMaxWriteSizeTooLarge as i32,
         "read_request_too_large"            => SMBEvent::ReadRequestTooLarge as i32,
         "read_response_too_large"           => SMBEvent::ReadResponseTooLarge as i32,
         "read_queue_size_too_large"         => SMBEvent::ReadResponseQueueSizeExceeded as i32,
index 3bb2155742752b326842ca57a07111bd69f810ee..f34ca682607ac3ace2cabcbcc15e267065ac153e 100644 (file)
@@ -2231,6 +2231,8 @@ pub extern "C" fn rs_smb_state_get_event_info_by_id(event_id: std::os::raw::c_in
             SMBEvent::FileOverlap => { "file_overlap\0" },
             SMBEvent::RequestToClient => { "request_to_client\0" },
             SMBEvent::ResponseToServer => { "response_to_server\0" },
+            SMBEvent::NegotiateMaxReadSizeTooLarge => { "negotiate_max_read_size_too_large\0" },
+            SMBEvent::NegotiateMaxWriteSizeTooLarge => { "negotiate_max_write_size_too_large\0" },
             SMBEvent::ReadRequestTooLarge => { "read_request_too_large\0" },
             SMBEvent::ReadResponseTooLarge => { "read_response_too_large\0" },
             SMBEvent::ReadResponseQueueSizeExceeded => { "read_queue_size_too_large\0" },
index 08e65ddeb939a89f097e6224ad73b0ca43ce2472..a050f7cfeb219519eddb503cfbb132ec93b4846f 100644 (file)
@@ -837,6 +837,15 @@ pub fn smb2_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
                 Ok((_, rd)) => {
                     SCLogDebug!("SERVER dialect => {}", &smb2_dialect_string(rd.dialect));
 
+                    let smb_cfg_max_read_size = unsafe { SMB_CFG_MAX_READ_SIZE };
+                    if smb_cfg_max_read_size != 0 && rd.max_read_size > smb_cfg_max_read_size {
+                        state.set_event(SMBEvent::NegotiateMaxReadSizeTooLarge);
+                    }
+                    let smb_cfg_max_write_size = unsafe { SMB_CFG_MAX_WRITE_SIZE };
+                    if smb_cfg_max_write_size != 0 && rd.max_write_size > smb_cfg_max_write_size {
+                        state.set_event(SMBEvent::NegotiateMaxWriteSizeTooLarge);
+                    }
+
                     state.dialect = rd.dialect;
                     state.max_read_size = rd.max_read_size;
                     state.max_write_size = rd.max_write_size;