]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
rust/probing: safety check for null input 11096/head
authorPhilippe Antoine <pantoine@oisf.net>
Tue, 7 May 2024 14:33:00 +0000 (16:33 +0200)
committerPhilippe Antoine <pantoine@oisf.net>
Fri, 17 May 2024 06:42:41 +0000 (08:42 +0200)
Ticket: 7013

Done consistently for all protocols

This may change some protocols behaviors which failed early
if they found there was not enough data...

(cherry picked from commit 37a9003736413b0bc9704099e189fd402922df43)

12 files changed:
rust/src/dcerpc/dcerpc.rs
rust/src/dcerpc/dcerpc_udp.rs
rust/src/dhcp/dhcp.rs
rust/src/dns/dns.rs
rust/src/krb/krb5.rs
rust/src/modbus/modbus.rs
rust/src/mqtt/mqtt.rs
rust/src/nfs/nfs.rs
rust/src/ntp/ntp.rs
rust/src/quic/quic.rs
rust/src/smb/smb.rs
rust/src/snmp/snmp.rs

index 759d5c26343ad22fe65fd222208feece56d2f2ca..3a1af7df5316fe0060890162b810347dc4a28ee1 100644 (file)
@@ -1293,7 +1293,7 @@ pub unsafe extern "C" fn rs_dcerpc_probe_tcp(_f: *const core::Flow, direction: u
                                       len: u32, rdir: *mut u8) -> AppProto
 {
     SCLogDebug!("Probing packet for DCERPC");
-    if len == 0 {
+    if len == 0 || input.is_null() {
         return core::ALPROTO_UNKNOWN;
     }
     let slice: &[u8] = std::slice::from_raw_parts(input as *mut u8, len as usize);
index 83707bddcb21ef1bb7155eff68246d4a4fc5f172..7c83bbc04a58ddcb624f3c01840f2cd97f712ff0 100644 (file)
@@ -311,7 +311,7 @@ pub unsafe extern "C" fn rs_dcerpc_probe_udp(_f: *const core::Flow, direction: u
                                       len: u32, rdir: *mut u8) -> core::AppProto
 {
     SCLogDebug!("Probing the packet for DCERPC/UDP");
-    if len == 0 {
+    if len == 0 || input.is_null() {
         return core::ALPROTO_UNKNOWN;
     }
     let slice: &[u8] = std::slice::from_raw_parts(input as *mut u8, len as usize);
index b69b675b8ce9dbb6a2c26f3077c2c796a788e4ff..7f0da5526e19daea38e718ee18024072f25eb83d 100644 (file)
@@ -184,7 +184,7 @@ pub unsafe extern "C" fn rs_dhcp_probing_parser(_flow: *const Flow,
                                          input_len: u32,
                                          _rdir: *mut u8) -> AppProto
 {
-    if input_len < DHCP_MIN_FRAME_LEN {
+    if input_len < DHCP_MIN_FRAME_LEN || input.is_null() {
         return ALPROTO_UNKNOWN;
     }
 
index 382c76ae59b5ac985d3be9ef548bd108e570322f..88a1e413ae751fcc22649ab6a30110792910350d 100644 (file)
@@ -917,7 +917,7 @@ pub unsafe extern "C" fn rs_dns_tx_get_query_rrtype(
 pub unsafe extern "C" fn rs_dns_probe(
     _flow: *const core::Flow, _dir: u8, input: *const u8, len: u32, rdir: *mut u8,
 ) -> AppProto {
-    if len == 0 || len < std::mem::size_of::<DNSHeader>() as u32 {
+    if input.is_null() || len < std::mem::size_of::<DNSHeader>() as u32 {
         return core::ALPROTO_UNKNOWN;
     }
     let slice: &[u8] = std::slice::from_raw_parts(input as *mut u8, len as usize);
@@ -938,7 +938,7 @@ pub unsafe extern "C" fn rs_dns_probe(
 pub unsafe extern "C" fn rs_dns_probe_tcp(
     _flow: *const core::Flow, direction: u8, input: *const u8, len: u32, rdir: *mut u8,
 ) -> AppProto {
-    if len == 0 || len < std::mem::size_of::<DNSHeader>() as u32 + 2 {
+    if input.is_null() || len < std::mem::size_of::<DNSHeader>() as u32 + 2 {
         return core::ALPROTO_UNKNOWN;
     }
     let slice: &[u8] = std::slice::from_raw_parts(input as *mut u8, len as usize);
index 3282d50ba78bc3c669e1efca2b7daa1460af424f..9ff0ff2157d9fbd364ad57a0d02fdd9804bf9a27 100644 (file)
@@ -363,6 +363,9 @@ pub unsafe extern "C" fn rs_krb5_probing_parser(_flow: *const Flow,
         input:*const u8, input_len: u32,
         _rdir: *mut u8) -> AppProto
 {
+    if input.is_null() {
+        return ALPROTO_UNKNOWN;
+    }
     let slice = build_slice!(input,input_len as usize);
     let alproto = ALPROTO_KRB5;
     if slice.len() <= 10 { return ALPROTO_FAILED; }
@@ -402,6 +405,9 @@ pub unsafe extern "C" fn rs_krb5_probing_parser_tcp(_flow: *const Flow,
         input:*const u8, input_len: u32,
         rdir: *mut u8) -> AppProto
 {
+    if input.is_null() {
+        return ALPROTO_UNKNOWN;
+    }
     let slice = build_slice!(input,input_len as usize);
     if slice.len() <= 14 { return ALPROTO_FAILED; }
     match be_u32(slice) as IResult<&[u8],u32> {
index 246e9cae6d6cd9e3eb7a8418d9cbefadf2747433..0008d748937cdefe6e0ef9f78bbe852c1c425b13 100644 (file)
@@ -274,6 +274,9 @@ impl ModbusState {
 pub extern "C" fn rs_modbus_probe(
     _flow: *const core::Flow, _direction: u8, input: *const u8, len: u32, _rdir: *mut u8,
 ) -> AppProto {
+    if input.is_null() {
+        return ALPROTO_UNKNOWN;
+    }
     let slice: &[u8] = unsafe { std::slice::from_raw_parts(input as *mut u8, len as usize) };
     match MODBUS_PARSER.probe(slice, Direction::Unknown) {
         Status::Recognized => unsafe { ALPROTO_MODBUS },
index 35f3c6d459a8a9d7d6d7d4f75a589aadc0598924..5d987de5a5fb2238d505f5d5731834b35334d03b 100644 (file)
@@ -616,6 +616,9 @@ impl MQTTState {
 pub unsafe extern "C" fn rs_mqtt_probing_parser(
     _flow: *const Flow, _direction: u8, input: *const u8, input_len: u32, _rdir: *mut u8,
 ) -> AppProto {
+    if input.is_null() {
+        return ALPROTO_UNKNOWN;
+    }
     let buf = build_slice!(input, input_len as usize);
     match parse_fixed_header(buf) {
         Ok((_, hdr)) => {
index 4a1c3624ef35ada04e228edebbba80a569b93d0d..b472689a5104056a79c1842742c00a3a2136c53f 100644 (file)
@@ -1881,6 +1881,9 @@ pub unsafe extern "C" fn rs_nfs_probe_ms(
         direction: u8, input: *const u8,
         len: u32, rdir: *mut u8) -> AppProto
 {
+    if input.is_null() {
+        return ALPROTO_UNKNOWN;
+    }
     let slice: &[u8] = build_slice!(input, len as usize);
     SCLogDebug!("rs_nfs_probe_ms: probing direction {:02x}", direction);
     let mut adirection : u8 = 0;
@@ -1920,6 +1923,9 @@ pub unsafe extern "C" fn rs_nfs_probe(_f: *const Flow,
                                _rdir: *mut u8)
     -> AppProto
 {
+    if input.is_null() {
+        return ALPROTO_UNKNOWN;
+    }
     let slice: &[u8] = build_slice!(input, len as usize);
     SCLogDebug!("rs_nfs_probe: running probe");
     match nfs_probe(slice, direction.into()) {
@@ -1938,6 +1944,9 @@ pub unsafe extern "C" fn rs_nfs_probe_udp_ts(_f: *const Flow,
                                _rdir: *mut u8)
     -> AppProto
 {
+    if input.is_null() {
+        return ALPROTO_UNKNOWN;
+    }
     let slice: &[u8] = build_slice!(input, len as usize);
     match nfs_probe_udp(slice, Direction::ToServer) {
         1 => { ALPROTO_NFS },
@@ -1955,6 +1964,9 @@ pub unsafe extern "C" fn rs_nfs_probe_udp_tc(_f: *const Flow,
                                _rdir: *mut u8)
     -> AppProto
 {
+    if input.is_null() {
+        return ALPROTO_UNKNOWN;
+    }
     let slice: &[u8] = build_slice!(input, len as usize);
     match nfs_probe_udp(slice, Direction::ToClient) {
         1 => { ALPROTO_NFS },
index c7b3b3d01826e9a4f8595b3411911dab1dcbd77a..3a06cfb8b14a6ec20defcbf4f40809a8b3ed60d9 100644 (file)
@@ -245,6 +245,9 @@ pub extern "C" fn ntp_probing_parser(_flow: *const Flow,
         input:*const u8, input_len: u32,
         _rdir: *mut u8) -> AppProto
 {
+    if input.is_null() {
+        return ALPROTO_UNKNOWN;
+    }
     let slice: &[u8] = unsafe { std::slice::from_raw_parts(input as *mut u8, input_len as usize) };
     let alproto = unsafe{ ALPROTO_NTP };
     match parse_ntp(slice) {
index 8e3ea6f35a21b1742da793cecb3aa547de99ef38..ec24ab81ee219efb229aac1ee99de29f59aed31f 100644 (file)
@@ -353,6 +353,9 @@ pub unsafe extern "C" fn rs_quic_state_tx_free(state: *mut std::os::raw::c_void,
 pub unsafe extern "C" fn rs_quic_probing_parser(
     _flow: *const Flow, _direction: u8, input: *const u8, input_len: u32, _rdir: *mut u8,
 ) -> AppProto {
+    if input.is_null() {
+        return ALPROTO_UNKNOWN;
+    }
     let slice = build_slice!(input, input_len as usize);
 
     if QuicHeader::from_bytes(slice, DEFAULT_DCID_LEN).is_ok() {
index 45d2cdc37a92eb496412a00184b73e5f2f6ca3f8..e64e0a8e6f0b75854d56d89f4685aa858a4758ce 100644 (file)
@@ -2121,7 +2121,7 @@ pub unsafe extern "C" fn rs_smb_probe_begins_tcp(_f: *const Flow,
                                    flags: u8, input: *const u8, len: u32, rdir: *mut u8)
     -> AppProto
 {
-    if len < MIN_REC_SIZE as u32 {
+    if len < MIN_REC_SIZE as u32 || input.is_null() {
         return ALPROTO_UNKNOWN;
     }
     let slice = build_slice!(input, len as usize);
@@ -2135,7 +2135,7 @@ pub unsafe extern "C" fn rs_smb_probe_tcp(_f: *const Flow,
                                    flags: u8, input: *const u8, len: u32, rdir: *mut u8)
     -> AppProto
 {
-    if len < MIN_REC_SIZE as u32 {
+    if len < MIN_REC_SIZE as u32 || input.is_null() {
         return ALPROTO_UNKNOWN;
     }
     let slice = build_slice!(input, len as usize);
index a4481f4bc191f487d961864c1272d3b7ab91cf01..6d67eb49e31cff62e3837407d307571643f3b5e3 100644 (file)
@@ -357,6 +357,9 @@ pub unsafe extern "C" fn rs_snmp_probing_parser(_flow: *const Flow,
                                          input:*const u8,
                                          input_len: u32,
                                          _rdir: *mut u8) -> AppProto {
+    if input.is_null() {
+        return ALPROTO_UNKNOWN;
+    }
     let slice = build_slice!(input,input_len as usize);
     let alproto = ALPROTO_SNMP;
     if slice.len() < 4 { return ALPROTO_FAILED; }