From: Victor Julien Date: Mon, 18 Apr 2022 19:47:39 +0000 (+0200) Subject: smb2: add options for max read/write size X-Git-Tag: suricata-5.0.9~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f9997f6ccd40c5d36fe329e3694c08a32fbca61a;p=thirdparty%2Fsuricata.git smb2: add options for max read/write size Add options for the max read/write size accepted by the parser. (cherry picked from commit 5bcc4162f7051194d228ba6c58a665d71c0c047c) --- diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs index 73bd3655a0..8bbc8f3558 100644 --- a/rust/src/smb/smb.rs +++ b/rust/src/smb/smb.rs @@ -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; +} diff --git a/rust/src/smb/smb2.rs b/rust/src/smb/smb2.rs index cdf9a44954..216a8681fa 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(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 {}", diff --git a/src/app-layer-smb.c b/src/app-layer-smb.c index 0b7f3bcab3..8db224a874 100644 --- a/src/app-layer-smb.c +++ b/src/app-layer-smb.c @@ -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);