diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs index cdb07a9a7b..641c47f6f0 100644 --- a/rust/src/smb/smb.rs +++ b/rust/src/smb/smb.rs @@ -73,6 +73,9 @@ pub enum SMBFrameType { pub const MIN_REC_SIZE: u16 = 32 + 4; // SMB hdr + nbss hdr pub const SMB_CONFIG_DEFAULT_STREAM_DEPTH: u32 = 0; +pub static mut SMB_CFG_MAX_READ_SIZE: u32 = 0; +pub static mut SMB_CFG_MAX_WRITE_SIZE: u32 = 0; + static mut ALPROTO_SMB: AppProto = ALPROTO_UNKNOWN; pub static mut SURICATA_SMB_FILE_CONFIG: Option<&'static SuricataFileContext> = None; @@ -2407,9 +2410,23 @@ pub unsafe extern "C" fn rs_smb_register_parser() { match get_memval(val) { Ok(retval) => { stream_depth = retval as u32; } Err(_) => { SCLogError!("Invalid depth value"); } - } + } AppLayerParserSetStreamDepth(IPPROTO_TCP as u8, ALPROTO_SMB, stream_depth); } + let retval = conf_get("app-layer.protocols.smb.max-read-size"); + if let Some(val) = retval { + match get_memval(val) { + Ok(retval) => { SMB_CFG_MAX_READ_SIZE = retval as u32; } + Err(_) => { SCLogError!("Invalid max-read-size value"); } + } + } + let retval = conf_get("app-layer.protocols.smb.max-write-size"); + if let Some(val) = retval { + match get_memval(val) { + Ok(retval) => { SMB_CFG_MAX_WRITE_SIZE = retval as u32; } + Err(_) => { SCLogError!("Invalid max-write-size value"); } + } + } } else { SCLogDebug!("Protocol detector and parser disabled for SMB."); } diff --git a/rust/src/smb/smb2.rs b/rust/src/smb/smb2.rs index 00d3e68697..834a2b1ede 100644 --- a/rust/src/smb/smb2.rs +++ b/rust/src/smb/smb2.rs @@ -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(Direction::ToClient, rd.len, rd.data.len() as u32); return; @@ -251,7 +253,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(Direction::ToServer, wr.wr_len, wr.data.len() as u32); return; @@ -492,7 +495,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 {}",