From: Philippe Antoine Date: Tue, 7 May 2024 14:33:00 +0000 (+0200) Subject: rust/probing: safety check for null input X-Git-Tag: suricata-7.0.6~74 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b5566192130db48e22ad88f511e0ad56b56ef2f8;p=thirdparty%2Fsuricata.git rust/probing: safety check for null input 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) --- diff --git a/rust/src/dcerpc/dcerpc.rs b/rust/src/dcerpc/dcerpc.rs index 759d5c2634..3a1af7df53 100644 --- a/rust/src/dcerpc/dcerpc.rs +++ b/rust/src/dcerpc/dcerpc.rs @@ -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); diff --git a/rust/src/dcerpc/dcerpc_udp.rs b/rust/src/dcerpc/dcerpc_udp.rs index 83707bddcb..7c83bbc04a 100644 --- a/rust/src/dcerpc/dcerpc_udp.rs +++ b/rust/src/dcerpc/dcerpc_udp.rs @@ -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); diff --git a/rust/src/dhcp/dhcp.rs b/rust/src/dhcp/dhcp.rs index b69b675b8c..7f0da5526e 100644 --- a/rust/src/dhcp/dhcp.rs +++ b/rust/src/dhcp/dhcp.rs @@ -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; } diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index 382c76ae59..88a1e413ae 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -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::() as u32 { + if input.is_null() || len < std::mem::size_of::() 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::() as u32 + 2 { + if input.is_null() || len < std::mem::size_of::() as u32 + 2 { return core::ALPROTO_UNKNOWN; } let slice: &[u8] = std::slice::from_raw_parts(input as *mut u8, len as usize); diff --git a/rust/src/krb/krb5.rs b/rust/src/krb/krb5.rs index 3282d50ba7..9ff0ff2157 100644 --- a/rust/src/krb/krb5.rs +++ b/rust/src/krb/krb5.rs @@ -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> { diff --git a/rust/src/modbus/modbus.rs b/rust/src/modbus/modbus.rs index 246e9cae6d..0008d74893 100644 --- a/rust/src/modbus/modbus.rs +++ b/rust/src/modbus/modbus.rs @@ -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 }, diff --git a/rust/src/mqtt/mqtt.rs b/rust/src/mqtt/mqtt.rs index 35f3c6d459..5d987de5a5 100644 --- a/rust/src/mqtt/mqtt.rs +++ b/rust/src/mqtt/mqtt.rs @@ -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)) => { diff --git a/rust/src/nfs/nfs.rs b/rust/src/nfs/nfs.rs index 4a1c3624ef..b472689a51 100644 --- a/rust/src/nfs/nfs.rs +++ b/rust/src/nfs/nfs.rs @@ -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 }, diff --git a/rust/src/ntp/ntp.rs b/rust/src/ntp/ntp.rs index c7b3b3d018..3a06cfb8b1 100644 --- a/rust/src/ntp/ntp.rs +++ b/rust/src/ntp/ntp.rs @@ -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) { diff --git a/rust/src/quic/quic.rs b/rust/src/quic/quic.rs index 8e3ea6f35a..ec24ab81ee 100644 --- a/rust/src/quic/quic.rs +++ b/rust/src/quic/quic.rs @@ -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() { diff --git a/rust/src/smb/smb.rs b/rust/src/smb/smb.rs index 45d2cdc37a..e64e0a8e6f 100644 --- a/rust/src/smb/smb.rs +++ b/rust/src/smb/smb.rs @@ -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); diff --git a/rust/src/snmp/snmp.rs b/rust/src/snmp/snmp.rs index a4481f4bc1..6d67eb49e3 100644 --- a/rust/src/snmp/snmp.rs +++ b/rust/src/snmp/snmp.rs @@ -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; }