@ -650,6 +650,14 @@ static int SortHelper(const void *a, const void *b)
return sa - > iid > sb - > iid ? 1 : - 1 ;
}
static inline bool SkipFwRules ( const Packet * p )
{
if ( p - > flow ! = NULL ) {
return ( p - > flow - > flags & FLOW_ACTION_ACCEPT ) ! = 0 ;
}
return false ;
}
static inline uint8_t DetectRulePacketRules ( ThreadVars * const tv ,
const DetectEngineCtx * const de_ctx , DetectEngineThreadCtx * const det_ctx , Packet * const p ,
Flow * const pflow , const DetectRunScratchpad * scratch )
@ -676,7 +684,7 @@ static inline uint8_t DetectRulePacketRules(ThreadVars *const tv,
RulesDumpMatchArray ( det_ctx , scratch - > sgh , p ) ;
# endif
bool skip_fw = false ;
bool skip_fw = SkipFwRules ( p ) ;
uint32_t sflags , next_sflags = 0 ;
if ( match_cnt ) {
next_s = * match_array + + ;
@ -863,12 +871,12 @@ static inline uint8_t DetectRulePacketRules(ThreadVars *const tv,
} else if ( as = = ACTION_SCOPE_PACKET ) {
/* accept:packet: break loop, return accept */
action | = s - > action ;
break_out_of_packet_filter = true ;
skip_fw = true ;
} else if ( as = = ACTION_SCOPE_FLOW ) {
/* accept:flow: break loop, return accept */
action | = s - > action ;
break_out_of_packet_filter = true ;
skip_fw = true ;
/* set immediately, as we're in hook "packet_filter" */
if ( pflow ) {
@ -887,7 +895,7 @@ next:
DetectReplaceFree ( det_ctx ) ;
RULE_PROFILING_END ( det_ctx , s , smatch , p ) ;
/* fw accept:packet or accept:flow means we're done here */
/* fw drop means we're done here */
if ( break_out_of_packet_filter )
break ;
@ -898,7 +906,7 @@ next:
* policy
*/
if ( have_fw_rules & & scratch - > default_action = = ACTION_DROP ) {
if ( ! fw_verdict) {
if ( ! skip_fw & & ! fw_verdict) {
DEBUG_VALIDATE_BUG_ON ( action & ACTION_DROP ) ;
PacketDrop ( p , ACTION_DROP , PKT_DROP_REASON_DEFAULT_PACKET_POLICY ) ;
action | = ACTION_DROP ;
@ -1571,6 +1579,15 @@ static enum DetectTxFirewallFlowControl DetectRunTxPreCheckFirewallPolicy(
DetectEngineThreadCtx * det_ctx , Packet * p , DetectTransaction * tx , const Signature * s ,
const uint32_t can_idx , bool * tx_fw_verdict , const bool last_tx )
{
if ( p - > flow - > flags & FLOW_ACTION_ACCEPT ) {
if ( ( * tx_fw_verdict ) = = false ) {
* tx_fw_verdict = true ;
DetectRunAppendDefaultAccept ( det_ctx , p ) ;
}
if ( s - > flags & SIG_FLAG_FIREWALL ) {
return DETECT_TX_FW_FC_SKIP ;
}
}
/* skip fw rules if we're in accept:tx mode */
if ( tx - > tx_data_ptr - > flags & APP_LAYER_TX_ACCEPT ) {
/* append a blank accept:packet action for the APP_LAYER_TX_ACCEPT,
@ -1939,6 +1956,11 @@ static void DetectRunTx(ThreadVars *tv,
/* if there are no rules / rule candidates, handling invoking the default
* policy . */
if ( have_fw_rules & & array_idx = = 0 ) {
if ( f - > flags & FLOW_ACTION_ACCEPT ) {
fw_verdicted + + ;
DetectRunAppendDefaultAccept ( det_ctx , p ) ;
return ;
}
if ( tx . tx_data_ptr - > flags & APP_LAYER_TX_ACCEPT ) {
fw_verdicted + + ;
@ -1956,19 +1978,21 @@ static void DetectRunTx(ThreadVars *tv,
}
}
bool fw_skip_app_filter = false ; /**< skip the rest of the app filter (fw) rules */
bool tx_fw_verdict = false ;
/* run rules: inspect the match candidates */
for ( uint32_t i = 0 ; i < array_idx ; i + + ) {
RuleMatchCandidateTx * can = & det_ctx - > tx_candidates [ i ] ;
const Signature * s = det_ctx - > tx_candidates [ i ] . s ;
uint32_t * inspect_flags = det_ctx - > tx_candidates [ i ] . flags ;
bool break_out_of_app_filter = false ;
SCLogDebug ( " % " PRIu64 " : sid:%u: %s tx %u/%u/%u sig %u " , p - > pcap_cnt , s - > id ,
flow_flags & STREAM_TOSERVER ? " toserver " : " toclient " , tx . tx_progress ,
tx . detect_progress , tx . detect_progress_orig , s - > app_progress_hook ) ;
if ( have_fw_rules ) {
if ( ( s - > flags & SIG_FLAG_FIREWALL ) ! = 0 & & fw_skip_app_filter )
continue ;
const enum DetectTxFirewallFlowControl fw_r = DetectRunTxPreCheckFirewallPolicy (
det_ctx , p , & tx , s , i , & tx_fw_verdict , last_tx ) ;
if ( fw_r = = DETECT_TX_FW_FC_SKIP )
@ -2003,13 +2027,11 @@ static void DetectRunTx(ThreadVars *tv,
if ( have_fw_rules & & ( s - > flags & SIG_FLAG_FIREWALL ) & &
( s - > action & ACTION_ACCEPT ) & & s - > app_progress_hook = = tx . tx_progress ) {
const bool fw_accept_to_packet = ApplyAcceptToPacket ( last_tx , & tx , s ) ;
break_out_of _app_filter = ApplyAccept ( p , flow_flags , s , & tx , tx_end_state ,
fw_skip _app_filter = ApplyAccept ( p , flow_flags , s , & tx , tx_end_state ,
fw_next_progress_missing , & tx_fw_verdict , & skip_fw_hook ,
& skip_before_progress ) ;
if ( fw_accept_to_packet )
DetectRunAppendDefaultAccept ( det_ctx , p ) ;
if ( break_out_of_app_filter )
break ;
}
continue ;
}
@ -2051,7 +2073,7 @@ static void DetectRunTx(ThreadVars *tv,
" %p/% " PRIu64 " sig %u (%u) matched " , tx . tx_ptr , tx . tx_id , s - > id , s - > iid ) ;
if ( ( s - > flags & SIG_FLAG_FIREWALL ) & & ( s - > action & ACTION_ACCEPT ) ) {
break_out_of _app_filter = ApplyAccept ( p , flow_flags , s , & tx , tx_end_state ,
fw_skip _app_filter = ApplyAccept ( p , flow_flags , s , & tx , tx_end_state ,
fw_next_progress_missing , & tx_fw_verdict , & skip_fw_hook ,
& skip_before_progress ) ;
/* see if we need to apply tx/hook accept to the packet. This can be needed when
@ -2075,7 +2097,7 @@ static void DetectRunTx(ThreadVars *tv,
/* if this rule was the last for our progress state, and it didn't match,
* we have to invoke the default drop policy . */
DetectFirewallApplyDefaultPolicy ( p , s - > alproto , s - > app_progress_hook ) ;
break_out_of _app_filter = true ;
fw_skip _app_filter = true ;
tx_fw_verdict = true ;
}
}
@ -2113,9 +2135,6 @@ static void DetectRunTx(ThreadVars *tv,
det_ctx - > post_rule_work_queue . len = 0 ;
PMQ_RESET ( & det_ctx - > pmq ) ;
}
if ( break_out_of_app_filter )
break ;
}
if ( tx_fw_verdict )
fw_verdicted + + ;
@ -2334,12 +2353,9 @@ static void DetectFlow(ThreadVars *tv,
}
/* in firewall mode, we still need to run the fw rulesets even for exception policy pass */
bool skip = false ;
if ( EngineModeIsFirewall ( ) ) {
skip = ( f - > flags & ( FLOW_ACTION_ACCEPT ) ) ;
} else {
skip = ( p - > flags & PKT_NOPACKET_INSPECTION | | f - > flags & ( FLOW_ACTION_PASS ) ) ;
bool skip = ( p - > flags & PKT_NOPACKET_INSPECTION | | f - > flags & ( FLOW_ACTION_PASS ) ) ;
if ( EngineModeIsFirewall ( ) & & ( f - > flags & FLOW_ACTION_ACCEPT ) = = 0 ) {
skip = false ;
}
if ( skip ) {
/* enfore prior accept:flow */