From: Victor Julien Date: Thu, 25 Jan 2018 16:55:17 +0000 (+0100) Subject: rust/nfs: explicitly handle GAPs from C X-Git-Tag: suricata-4.1.0-beta1~288 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e8939335eaccd9cf20141f299e8781c210af863b;p=thirdparty%2Fsuricata.git rust/nfs: explicitly handle GAPs from C It seems that Rust optimizes this code in such a way that it passes the null ptr along as real data. if buf.as_ptr().is_null() && input_len > 0 { --- diff --git a/rust/src/nfs/nfs.rs b/rust/src/nfs/nfs.rs index ff0e0558f2..4eb2fe7a02 100644 --- a/rust/src/nfs/nfs.rs +++ b/rust/src/nfs/nfs.rs @@ -1725,9 +1725,9 @@ pub extern "C" fn rs_nfs3_state_free(state: *mut libc::c_void) { nfs3_state.free(); } -/// C binding parse a DNS request. Returns 1 on success, -1 on failure. +/// C binding parse a NFS TCP request. Returns 1 on success, -1 on failure. #[no_mangle] -pub extern "C" fn rs_nfs3_parse_request(_flow: *mut Flow, +pub extern "C" fn rs_nfs_parse_request(_flow: *mut Flow, state: &mut NFSState, _pstate: *mut libc::c_void, input: *mut libc::uint8_t, @@ -1738,13 +1738,6 @@ pub extern "C" fn rs_nfs3_parse_request(_flow: *mut Flow, let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)}; SCLogDebug!("parsing {} bytes of request data", input_len); - if buf.as_ptr().is_null() && input_len > 0 { - if state.parse_tcp_data_ts_gap(input_len as u32) == 0 { - return 1 - } - return -1 - } - if state.parse_tcp_data_ts(buf) == 0 { 1 } else { @@ -1753,7 +1746,19 @@ pub extern "C" fn rs_nfs3_parse_request(_flow: *mut Flow, } #[no_mangle] -pub extern "C" fn rs_nfs3_parse_response(_flow: *mut Flow, +pub extern "C" fn rs_nfs_parse_request_tcp_gap( + state: &mut NFSState, + input_len: libc::uint32_t) + -> libc::int8_t +{ + if state.parse_tcp_data_ts_gap(input_len as u32) == 0 { + return 1; + } + return -1; +} + +#[no_mangle] +pub extern "C" fn rs_nfs_parse_response(_flow: *mut Flow, state: &mut NFSState, _pstate: *mut libc::c_void, input: *mut libc::uint8_t, @@ -1764,13 +1769,6 @@ pub extern "C" fn rs_nfs3_parse_response(_flow: *mut Flow, SCLogDebug!("parsing {} bytes of response data", input_len); let buf = unsafe{std::slice::from_raw_parts(input, input_len as usize)}; - if buf.as_ptr().is_null() && input_len > 0 { - if state.parse_tcp_data_tc_gap(input_len as u32) == 0 { - return 1 - } - return -1 - } - if state.parse_tcp_data_tc(buf) == 0 { 1 } else { @@ -1778,6 +1776,18 @@ pub extern "C" fn rs_nfs3_parse_response(_flow: *mut Flow, } } +#[no_mangle] +pub extern "C" fn rs_nfs_parse_response_tcp_gap( + state: &mut NFSState, + input_len: libc::uint32_t) + -> libc::int8_t +{ + if state.parse_tcp_data_tc_gap(input_len as u32) == 0 { + return 1; + } + return -1; +} + /// C binding parse a DNS request. Returns 1 on success, -1 on failure. #[no_mangle] pub extern "C" fn rs_nfs3_parse_request_udp(_flow: *mut Flow, diff --git a/src/app-layer-nfs-tcp.c b/src/app-layer-nfs-tcp.c index 1c68dd0b7b..676e21cef5 100644 --- a/src/app-layer-nfs-tcp.c +++ b/src/app-layer-nfs-tcp.c @@ -160,7 +160,13 @@ static int NFSTCPParseRequest(Flow *f, void *state, uint16_t file_flags = FileFlowToFlags(f, STREAM_TOSERVER); rs_nfs3_setfileflags(0, state, file_flags); - return rs_nfs3_parse_request(f, state, pstate, input, input_len, local_data); + int res; + if (input == NULL && input_len > 0) { + res = rs_nfs_parse_request_tcp_gap(state, input_len); + } else { + res = rs_nfs_parse_request(f, state, pstate, input, input_len, local_data); + } + return res; } static int NFSTCPParseResponse(Flow *f, void *state, AppLayerParserState *pstate, @@ -169,7 +175,13 @@ static int NFSTCPParseResponse(Flow *f, void *state, AppLayerParserState *pstate uint16_t file_flags = FileFlowToFlags(f, STREAM_TOCLIENT); rs_nfs3_setfileflags(1, state, file_flags); - return rs_nfs3_parse_response(f, state, pstate, input, input_len, local_data); + int res; + if (input == NULL && input_len > 0) { + res = rs_nfs_parse_response_tcp_gap(state, input_len); + } else { + res = rs_nfs_parse_response(f, state, pstate, input, input_len, local_data); + } + return res; } static uint64_t NFSTCPGetTxCnt(void *state)