From b9e504683eb964496fb2af23e4c24cead6b29746 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Thu, 7 Feb 2013 16:52:06 -0800 Subject: [PATCH] Prevent a state action from invoking another one. Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 34 ++++++++++++++++-------------- Shorewall/Perl/Shorewall/Rules.pm | 31 +++++++++++++++------------ Shorewall/action.Established | 2 +- Shorewall/action.Invalid | 2 +- Shorewall/action.Related | 2 +- Shorewall/action.Untracked | 2 +- Shorewall/actions.std | 2 +- 7 files changed, 41 insertions(+), 34 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 52b965a2b..188565511 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -95,6 +95,7 @@ our @EXPORT = ( qw( HELPER INLINE TERMINATING + STATEMATCH %chain_table %targets @@ -346,22 +347,23 @@ our %nfobjects; # # Target Types # -use constant { STANDARD => 0x1, #defined by Netfilter - NATRULE => 0x2, #Involves NAT - BUILTIN => 0x4, #A built-in action - NONAT => 0x8, #'NONAT' or 'ACCEPT+' - NATONLY => 0x10, #'DNAT-' or 'REDIRECT-' - REDIRECT => 0x20, #'REDIRECT' - ACTION => 0x40, #An action (may be built-in) - MACRO => 0x80, #A Macro - LOGRULE => 0x100, #'LOG','NFLOG' - NFQ => 0x200, #'NFQUEUE' - CHAIN => 0x400, #Manual Chain - SET => 0x800, #SET - AUDIT => 0x1000, #A_ACCEPT, etc - HELPER => 0x2000, #CT:helper - NFLOG => 0x4000, #NFLOG or ULOG - INLINE => 0x8000, #Inline action +use constant { STANDARD => 0x1, #defined by Netfilter + NATRULE => 0x2, #Involves NAT + BUILTIN => 0x4, #A built-in action + NONAT => 0x8, #'NONAT' or 'ACCEPT+' + NATONLY => 0x10, #'DNAT-' or 'REDIRECT-' + REDIRECT => 0x20, #'REDIRECT' + ACTION => 0x40, #An action (may be built-in) + MACRO => 0x80, #A Macro + LOGRULE => 0x100, #'LOG','NFLOG' + NFQ => 0x200, #'NFQUEUE' + CHAIN => 0x400, #Manual Chain + SET => 0x800, #SET + AUDIT => 0x1000, #A_ACCEPT, etc + HELPER => 0x2000, #CT:helper + NFLOG => 0x4000, #NFLOG or ULOG + INLINE => 0x8000, #Inline action + STATEMATCH => 0x10000, #action.Invalid, action.Related, etc. }; # # Valid Targets -- value is a combination of one or more of the above diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index 9d41e4d0a..704a14735 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -1664,7 +1664,7 @@ sub process_actions() { } -sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ); +sub process_rule ( $$$$$$$$$$$$$$$$$$$ ); # # Populate an action invocation chain. As new action tuples are encountered, @@ -1720,7 +1720,6 @@ sub process_action($$) { process_rule( $chainref, '', - 0, $nolog ? $target : merge_levels( join(':', @actparms{'chain','loglevel','logtag'}), $target ), '', $source, @@ -1866,7 +1865,6 @@ sub process_macro ($$$$$$$$$$$$$$$$$$$$) { $generated |= process_rule( $chainref, $matches, - 0, $mtarget, $param, $msource, @@ -1986,7 +1984,6 @@ sub process_inline ($$$$$$$$$$$$$$$$$$$$$) { $generated |= process_rule( $chainref, $matches, - 0, $mtarget, $param, $msource, @@ -2039,10 +2036,9 @@ sub verify_audit($;$$) { # reference is also passed when rules are being generated during processing of a macro used as a default action. # -sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) { +sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) { my ( $chainref, #reference to Action Chain if we are being called from process_action(); undef otherwise $rule, #Matches - $actiontype, $target, $current_param, $source, @@ -2064,6 +2060,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) { my ( $action, $loglevel) = split_action $target; my ( $basictarget, $param ) = get_target_param $action; my $optimize = $wildcard ? ( $basictarget =~ /!$/ ? 0 : $config{OPTIMIZE} & 5 ) : 0; + my $actiontype; my $inaction = ''; # Set to true when we are process rules in an action file my $inchain = ''; # Set to true when a chain reference is passed. my $normalized_target; @@ -2080,7 +2077,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$$ ) { # # Determine the validity of the action # - $actiontype = ( $targets{$basictarget} || find_macro ( $basictarget ) ) unless $actiontype; + $actiontype = ( $targets{$basictarget} || find_macro ( $basictarget ) ); if ( $config{ MAPOLDACTIONS } ) { ( $basictarget, $actiontype , $param ) = map_old_actions( $basictarget ) unless $actiontype || supplied $param; @@ -2755,26 +2752,33 @@ sub merge_target( $$ ) { # May be called by Perl code in action bodies (regular and inline) to generate a rule. # sub perl_action_helper($$;$) { - my ( $target, $matches, $actiontype ) = @_; + my ( $target, $matches, $isstatematch ) = @_; my $action = $actparms{action}; my $chainref = $actparms{0}; my $result; + our $statematch; + assert( $chainref ); $matches .= ' ' unless $matches =~ /^(?:.+\s)?$/; + if ( $isstatematch ) { + return if $statematch; + $statematch = 1; + } + if ( my $ref = $inlines{$action} ) { $result = &process_rule( $chainref, $matches, - $actiontype || 0, merge_target( $ref, $target ), '', # CurrentParam @columns ); } else { + assert $actions{$action}; + $result = process_rule( $chainref, $matches, - $actiontype || 0, merge_target( $actions{$action}, $target ), '', # Current Param '-', # Source @@ -2799,6 +2803,8 @@ sub perl_action_helper($$;$) { # Record that we generated a rule to avoid bogus warning # $actionresult ||= $result; + + $statematch = 0 if $isstatematch; } # @@ -2822,7 +2828,6 @@ sub perl_action_tcp_helper($$) { if ( my $ref = $inlines{$action} ) { $result = &process_rule( $chainref, $proto, - 0, merge_target( $ref, $target ), '', @columns[0,1], @@ -2832,7 +2837,6 @@ sub perl_action_tcp_helper($$) { } else { $result = process_rule( $chainref, $proto, - 0, merge_target( $actions{$action}, $target ), '', # Current Param '-', # Source @@ -2991,6 +2995,8 @@ sub process_raw_rule ( ) { my @users = split_list1 $users, 'USER/GROUP'; my $generated = 0; + our $statematch = 0; + fatal_error "Invalid or missing ACTION ($target)" unless defined $action; if ( @protos > 1 ) { @@ -3007,7 +3013,6 @@ sub process_raw_rule ( ) { for my $user ( @users ) { if ( process_rule( undef, '', - 0, $target, '', $source, diff --git a/Shorewall/action.Established b/Shorewall/action.Established index e8c3489db..47ff0d5ac 100644 --- a/Shorewall/action.Established +++ b/Shorewall/action.Established @@ -41,7 +41,7 @@ use Shorewall::Rules; my ( $action ) = get_action_params( 1 ); if ( my $check = check_state( 'ESTABLISHED' ) ) { - perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} ESTABLISHED" : '' ); + perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} ESTABLISHED" : '', 1 ); } 1; diff --git a/Shorewall/action.Invalid b/Shorewall/action.Invalid index e7b35fa75..52595fe5c 100644 --- a/Shorewall/action.Invalid +++ b/Shorewall/action.Invalid @@ -46,7 +46,7 @@ if ( supplied $audit ) { } if ( my $check = check_state( 'INVALID' ) ) { - perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} INVALID" : '' ); + perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} INVALID" : '' , 1 ); } 1; diff --git a/Shorewall/action.Related b/Shorewall/action.Related index cb76de209..8e0d666fe 100644 --- a/Shorewall/action.Related +++ b/Shorewall/action.Related @@ -42,7 +42,7 @@ use Shorewall::Rules; my ( $action ) = get_action_params( 1 ); if ( my $check = check_state( 'RELATED' ) ) { - perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} RELATED" : '' ); + perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} RELATED" : '', 1 ); } 1; diff --git a/Shorewall/action.Untracked b/Shorewall/action.Untracked index 6270d6fd5..eb71af255 100644 --- a/Shorewall/action.Untracked +++ b/Shorewall/action.Untracked @@ -41,7 +41,7 @@ use Shorewall::Rules; my ( $action ) = get_action_params( 1 ); if ( my $check = check_state( 'UNTRACKED' ) ) { - perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} UNTRACKED" : '' ); + perl_action_helper( $action, $check == 1 ? "$globals{STATEMATCH} UNTRACKED" : '' , 1 ); } 1; diff --git a/Shorewall/actions.std b/Shorewall/actions.std index 6fd80d72e..c72eac69f 100644 --- a/Shorewall/actions.std +++ b/Shorewall/actions.std @@ -40,4 +40,4 @@ Reject # Default Action for REJECT policy Related inline # Handles packets in the RELATED conntrack state RST inline # Handle packets with RST set TCPFlags # Handle bad flag combinations. -Untracked inline # Handles packets in the UNTRACKED conntrack state +Untracked inline # Handles packets in the UNTRACKED conntrack state