From 9f9c29a14a91f86c1bda92285e876e026dc9e3a4 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Fri, 23 Oct 2020 10:26:42 +0200 Subject: [PATCH] dcerpc: fix stream flag handling 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 | 13 ++++++++++--- src/app-layer-dcerpc.c | 8 ++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/rust/src/dcerpc/dcerpc.rs b/rust/src/dcerpc/dcerpc.rs index fac3a53397..0020bc35cc 100644 --- a/rust/src/dcerpc/dcerpc.rs +++ b/rust/src/dcerpc/dcerpc.rs @@ -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() diff --git a/src/app-layer-dcerpc.c b/src/app-layer-dcerpc.c index 5d1c391729..40cd753bf0 100644 --- a/src/app-layer-dcerpc.c +++ b/src/app-layer-dcerpc.c @@ -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); -- 2.47.2