]> 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, 29 Jan 2018 10:44:01 +0000 (11:44 +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 ff0e0558f2108c040029a017c284dd3c92b521ea..4eb2fe7a02d8b9776db9bfc701c5216f3158f89d 100644 (file)
@@ -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,
index 1c68dd0b7be04adf6c19f4d96680586f30f1a3e8..676e21cef5a3a62a5ebc0d36607c0830fa994335 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)