]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
rust/probing: safety check for null input
authorPhilippe Antoine <pantoine@oisf.net>
Tue, 7 May 2024 14:33:00 +0000 (16:33 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 15 May 2024 15:03:50 +0000 (17:03 +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...

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 b17cc8d1fa8bf0e694ccf84a8fd7ddd7bf430ea2..2007c867bfae090e97e766727830a1da4007c85c 100644 (file)
@@ -310,7 +310,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 587054dab6ee9c5c65d33f3ab4a686e23fe75786..045adbe2185eb042900789fd36896ffcb03970b6 100644 (file)
@@ -896,7 +896,7 @@ pub extern "C" fn SCDnsTxGetResponseFlags(tx: &mut DNSTransaction) -> u16 {
 unsafe extern "C" fn probe_udp(
     _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);
@@ -916,7 +916,7 @@ unsafe extern "C" fn probe_udp(
 unsafe extern "C" fn c_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 ddcca94b291c7b7ee6e6a887025db9fe636964ef..aceeb86d2b470a4395c819dc8013847e7c78a859 100644 (file)
@@ -364,6 +364,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; }
@@ -403,6 +406,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 1c0ecc884dd57eef9d2a2577fcd5e128d390c4dc..18e98089b2519a9e37f00c9d962e12aeeddf2908 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 66067eb6fa39320ca0ca3b8438abc11d0c738b92..dace75c8ecb55aee7cf4f002ffef25ab12592e8b 100644 (file)
@@ -619,6 +619,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 98fb56b7e4be416413a7bf37789a8ef1fd0cdb4f..cb07ef63030b6d72b581bca02a941337caaf515e 100644 (file)
@@ -1861,6 +1861,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;
@@ -1900,6 +1903,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()) {
@@ -1918,6 +1924,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 },
@@ -1935,6 +1944,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 473a7df4271c0afe4f255f9abfd35cd401542a75..330b0f8d379d0e37e677e0efca1321692ba92c49 100644 (file)
@@ -376,6 +376,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 fbbb636e89e1a487a545c9b5b46d52fa4ff54200..56e1685e307902206326e8f028521d081cf3a5d0 100644 (file)
@@ -2115,7 +2115,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);
@@ -2129,7 +2129,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 3b78b47f7a1d957a7ee4700e866e7fd1f8fb47d5..3e68f70b08e6228728b9e0d2271f424463fe8f26 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; }