]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
smb: check on param parsing
authorPhilippe Antoine <contact@catenacyber.fr>
Mon, 4 Apr 2022 20:45:56 +0000 (22:45 +0200)
committerJeff Lucovsky <jeff@lucovsky.org>
Sun, 29 May 2022 19:23:24 +0000 (15:23 -0400)
Ticket: 5246

so as not to overflow u16

(cherry picked from commit 817a5001a50a90800547e66fef067c0443eb9f72)

rust/src/smb/smb1_records.rs

index 18f80d93ef41eef6dd63db3ae68c76e91863e80c..8747ef84e3d2aa1d4a51e4475c526b7437c51fe4 100644 (file)
  */
 
 use crate::smb::error::SmbError;
-use nom::IResult;
-use nom::combinator::rest;
-use nom::number::streaming::{le_u8, le_u16, le_u32, le_u64};
 use crate::smb::smb::*;
 use crate::smb::smb_records::*;
+use nom::bytes::streaming:: take;
+use nom::combinator::{cond, rest, verify};
+use nom::number::streaming::{le_u8, le_u16, le_u32, le_u64};
+use nom::IResult;
+
 
 // SMB_FLAGS_REPLY in Microsoft docs.
 const SMB1_FLAGS_RESPONSE: u8 = 0x80;
@@ -656,37 +658,41 @@ pub struct SmbRequestTrans2Record<'a> {
     pub data_blob: &'a[u8],
 }
 
-named!(pub parse_smb_trans2_request_record<SmbRequestTrans2Record>,
-    do_parse!(
-            _wct: le_u8
-        >>  _total_param_cnt: le_u16
-        >>  _total_data_cnt: le_u16
-        >>  _max_param_cnt: le_u16
-        >>  _max_data_cnt: le_u16
-        >>  _max_setup_cnt: le_u8
-        >>  _reserved1: take!(1)
-        >>  _flags: le_u16
-        >>  _timeout: le_u32
-        >>  _reserved2: take!(2)
-        >>  param_cnt: le_u16
-        >>  _param_offset: le_u16
-        >>  data_cnt: le_u16
-        >>  _data_offset: le_u16
-        >>  _setup_cnt: le_u8
-        >>  _reserved3: take!(1)
-        >>  subcmd: le_u16
-        >>  _bcc: le_u16
-        >>  _padding: take!(3)
-        //TODO test and use _param_offset and _data_offset
-        >>  setup_blob: take!(param_cnt)
-        >>  data_blob: take!(data_cnt)
-
-        >> (SmbRequestTrans2Record {
-                subcmd,
-                setup_blob,
-                data_blob
-           }))
-);
+pub fn parse_smb_trans2_request_record(i: &[u8]) -> IResult<&[u8], SmbRequestTrans2Record> {
+    let (i, _wct) = le_u8(i)?;
+    let (i, _total_param_cnt) = le_u16(i)?;
+    let (i, _total_data_cnt) = le_u16(i)?;
+    let (i, _max_param_cnt) = le_u16(i)?;
+    let (i, _max_data_cnt) = le_u16(i)?;
+    let (i, _max_setup_cnt) = le_u8(i)?;
+    let (i, _reserved1) = take(1_usize)(i)?;
+    let (i, _flags) = le_u16(i)?;
+    let (i, _timeout) = le_u32(i)?;
+    let (i, _reserved2) = take(2_usize)(i)?;
+    let (i, param_cnt) = le_u16(i)?;
+    let (i, param_offset) = verify(le_u16, |&v| v <= (std::u16::MAX - param_cnt))(i)?;
+    let (i, data_cnt) = le_u16(i)?;
+    let (i, data_offset) = le_u16(i)?;
+    let (i, _setup_cnt) = le_u8(i)?;
+    let (i, _reserved3) = take(1_usize)(i)?;
+    let (i, subcmd) = le_u16(i)?;
+    let (i, _bcc) = le_u16(i)?;
+    //TODO test and use param_offset
+    let (i, _padding) = take(3_usize)(i)?;
+    let (i, setup_blob) = take(param_cnt)(i)?;
+    let (i, _padding2) = cond(
+        data_offset > param_offset + param_cnt,
+        |b| take(data_offset - param_offset - param_cnt)(b)
+    )(i)?;
+    let (i, data_blob) = take(data_cnt)(i)?;
+
+    let record = SmbRequestTrans2Record {
+        subcmd,
+        setup_blob,
+        data_blob
+    };
+    Ok((i, record))
+}
 
 #[derive(Debug,PartialEq)]
 pub struct SmbResponseCreateAndXRecord<'a> {