> On 31 Aug 2015, at 22:57, Alexandr Nedvedicky 
> <[email protected]> wrote:
> 
> Hello,
> 
> Dilli Paudel in Oracle was playing with PF enough to find funny glitch.
> He used rule as follows:
> 
>       block in on vnic4 from 192.168.1.0/24 to any route-to 172.16.1.1@vnic5
> 
> Many people expect the route-to action is somewhat futile as 'block' action
> takes precedence here, so packet gets always dropped. Well the reality is
> very different (and still makes a sort of sense) from PF point of view.
> The snippet comes from pf_test():
> 
>    6586         switch (action) {
>    6587         case PF_SYNPROXY_DROP:
>    ....
>    6593         case PF_DIVERT:
>    6594                 switch (pd.af) {
>    6595                 case AF_INET:
>    ....
>    6610         case PF_AFRT:
>    6611                 if (pf_translate_af(&pd)) {
>    ....
>    6624 #endif /* INET6 */
>    6625         default:
>    6626                 /* pf_route can free the mbuf causing *m0 to become 
> NULL */
>    6627                 if (r->rt) {
>    6628                         switch (pd.af) {
>    6629                         case AF_INET:
>    6630                                 pf_route(m0, r, pd.dir, 
> pd.kif->pfik_ifp, s);
>    6631                                 break;
> 
> the action comes from matching rule. It's PF_DROP in case of Dilli's rule.  As
> you can see there is no case-branch for PF_DROP in switch statement at line
> 6586, so a default: is executed. For route-to action the r->rt is set and PF
> executes the route_to*().
> 
> Dilli  suggests to introduce PF_DROP case branch to switch() at line 6586 
> Issue
> has been also discussed on Friday over icb, where Mr. bluhm further suggested
> we should try to add some sanity check to parse.y.
> 
> As a side effect the patch breaks block rules with dup-to action. dup-to
> action as a part of block rule might make some sense... So if there is
> someone, who really needs block ... dup-to he should opt for equivalent
> rule using pass ... route-to 
> 
> Also there is one more question:
> 
>    shall we implement similar sanity checks for nat-to/rdr-to/... actions?

IMHO, yes that would make sense.

Some bike shedding inline below, apart from that, ok jung@

> no one should expect those in block rule, so making pfctl to refuse such rules
> loudly sounds like a right thing to do...
> 
> regards
> sasha
> 
> --------8<---------------8<---------------8<------------------8<--------
> 
> Index: sbin/pfctl/parse.y
> ===================================================================
> RCS file: /cvs/src/sbin/pfctl/parse.y,v
> retrieving revision 1.648
> diff -u -p -r1.648 parse.y
> --- sbin/pfctl/parse.y        21 Apr 2015 16:34:59 -0000      1.648
> +++ sbin/pfctl/parse.y        31 Aug 2015 20:30:56 -0000
> @@ -3997,8 +3997,11 @@ rule_consistent(struct pf_rule *r, int a
>               problems++;
>       }
> 
> -     /* match rules rules */

Sad, I think this comment is funny enough to keep it :)

> -     if (r->action == PF_MATCH) {
> +     /* 
> +      * Basic rule sanity check.
> +      */

A single line comment is enough here, isn’t it?

> +     switch (r->action) {
> +     case PF_MATCH:
>               if (r->divert.port) {
>                       yyerror("divert is not supported on match rules");
>                       problems++;
> @@ -4016,6 +4019,15 @@ rule_consistent(struct pf_rule *r, int a
>                       yyerror("af-to is not supported on match rules");
>                       problems++;
>               }
> +             break;
> +     case PF_DROP:
> +             if (r->rt) {
> +                     yyerror("route-to, reply-to and dup-to "
> +                        "must not be used on block rules”);

The other error messages say “is not supported” instead of “must no be used”.
I do not care which wording you chose, but maybe take the chance and unify it, 
to be more consistent here? 

> +                     problems++;
> +             }
> +             break;
> +     default:;
>       }
>       return (-problems);
> }
> Index: sys/net/pf.c
> ===================================================================
> RCS file: /cvs/src/sys/net/pf.c,v
> retrieving revision 1.936
> diff -u -p -r1.936 pf.c
> --- sys/net/pf.c      19 Aug 2015 21:22:41 -0000      1.936
> +++ sys/net/pf.c      31 Aug 2015 20:31:02 -0000
> @@ -6622,6 +6622,10 @@ done:
>               action = PF_PASS;
>               break;
> #endif /* INET6 */
> +     case PF_DROP:
> +             m_freem(*m0);
> +             *m0 = NULL;
> +             break;
>       default:
>               /* pf_route can free the mbuf causing *m0 to become NULL */
>               if (r->rt) {
> 


Reply via email to