]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
dcerpc: fix stream flag handling
authorVictor Julien <victor@inliniac.net>
Fri, 23 Oct 2020 08:26:42 +0000 (10:26 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 4 Nov 2020 15:30:37 +0000 (16:30 +0100)
Only hardcoded direction flags were passed to the parser, not the
full range.

Handle receiving an EOF flag w/o data.

Bug: #3856

rust/src/dcerpc/dcerpc.rs
src/app-layer-dcerpc.c

index fac3a53397d9a05dcf0baf40d3741ec3e8e0206b..0020bc35cc1977b184355f4b8148cc3a5cd42df3 100644 (file)
@@ -1142,14 +1142,18 @@ pub extern "C" fn rs_dcerpc_parse_request(
     _flow: *mut core::Flow, state: &mut DCERPCState, _pstate: *mut std::os::raw::c_void,
     input: *const u8, input_len: u32, _data: *mut std::os::raw::c_void, flags: u8,
 ) -> AppLayerResult {
-    SCLogDebug!("Handling request");
+    SCLogDebug!("Handling request: input {:p} input_len {} flags {:x} EOF {}",
+            input, input_len, flags, flags & core::STREAM_EOF != 0);
+    if flags & core::STREAM_EOF != 0 && input_len == 0 {
+        return AppLayerResult::ok();
+    }
     /* START with MIDSTREAM set: record might be starting the middle. */
     if flags & (core::STREAM_START|core::STREAM_MIDSTREAM) == (core::STREAM_START|core::STREAM_MIDSTREAM) {
         state.ts_gap = true;
     }
     if input_len > 0 && input != std::ptr::null_mut() {
         let buf = build_slice!(input, input_len as usize);
-        return state.handle_input_data(buf, flags);
+        return state.handle_input_data(buf, core::STREAM_TOSERVER);
     }
     AppLayerResult::err()
 }
@@ -1159,6 +1163,9 @@ pub extern "C" fn rs_dcerpc_parse_response(
     _flow: *mut core::Flow, state: &mut DCERPCState, _pstate: *mut std::os::raw::c_void,
     input: *const u8, input_len: u32, _data: *mut std::os::raw::c_void, flags: u8,
 ) -> AppLayerResult {
+    if flags & core::STREAM_EOF != 0 && input_len == 0 {
+        return AppLayerResult::ok();
+    }
     /* START with MIDSTREAM set: record might be starting the middle. */
     if flags & (core::STREAM_START|core::STREAM_MIDSTREAM) == (core::STREAM_START|core::STREAM_MIDSTREAM) {
         state.tc_gap = true;
@@ -1166,7 +1173,7 @@ pub extern "C" fn rs_dcerpc_parse_response(
     if input_len > 0 {
         if input != std::ptr::null_mut() {
             let buf = build_slice!(input, input_len as usize);
-            return state.handle_input_data(buf, flags);
+            return state.handle_input_data(buf, core::STREAM_TOCLIENT);
         }
     }
     AppLayerResult::err()
index 5d1c391729c0734ca45749af1d6d40a334e083b8..40cd753bf0a2ac9bcf5551ddbf342de87b55f1b0 100644 (file)
@@ -55,8 +55,8 @@ static AppLayerResult DCERPCParseRequest(Flow *f, void *dcerpc_state,
         SCLogDebug("DCERPC request GAP of %u bytes, retval %d", input_len, res.status);
         SCReturnStruct(res);
     } else {
-        AppLayerResult res = rs_dcerpc_parse_request(f, dcerpc_state, pstate, input, input_len,
-                                                     local_data, 0x04);
+        AppLayerResult res = rs_dcerpc_parse_request(
+                f, dcerpc_state, pstate, input, input_len, local_data, flags);
         SCLogDebug("DCERPC request%s of %u bytes, retval %d",
                 (input == NULL && input_len > 0) ? " is GAP" : "", input_len, res.status);
         SCReturnStruct(res);
@@ -73,8 +73,8 @@ static AppLayerResult DCERPCParseResponse(Flow *f, void *dcerpc_state,
         SCLogDebug("DCERPC response GAP of %u bytes, retval %d", input_len, res.status);
         SCReturnStruct(res);
     } else {
-        AppLayerResult res = rs_dcerpc_parse_response(f, dcerpc_state, pstate, input, input_len,
-                                                      local_data, 0x08);
+        AppLayerResult res = rs_dcerpc_parse_response(
+                f, dcerpc_state, pstate, input, input_len, local_data, flags);
         SCLogDebug("DCERPC response%s of %u bytes, retval %d",
                 (input == NULL && input_len > 0) ? " is GAP" : "", input_len, res.status);
         SCReturnStruct(res);