]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
rust/nfs: explicitly handle GAPs from C
authorVictor Julien <victor@inliniac.net>
Thu, 25 Jan 2018 16:55:17 +0000 (17:55 +0100)
committerVictor Julien <victor@inliniac.net>
Mon, 12 Feb 2018 09:02:08 +0000 (10:02 +0100)
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 {

rust/src/nfs/nfs.rs
src/app-layer-nfs-tcp.c

index 04426f54a7167f2b5ad7f4a315b5e58fa5aaa612..859c5222d7a26d174376b33c97ebaff059179ab6 100644 (file)
@@ -1720,9 +1720,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,
@@ -1733,13 +1733,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 {
@@ -1748,7 +1741,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,
@@ -1759,13 +1764,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 {
@@ -1773,6 +1771,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,
index bdb6545cd762944956b4264b2eedc9c4f9a48f7d..401c9e699374bf79d25121c2acfd77de8a89c294 100644 (file)
@@ -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)