On Thu, May 21, 2015 at 11:07 +0200, Alexandr Nedvedicky wrote:
> Hello,
> 
> > On Tue, May 19, 2015 at 14:07 +0200, Alexandr Nedvedicky wrote:
> > > Hello Mike,
> > > 
> > > I've reworked patch from yesterday. I've done some quick testing
> > > to see if it fixes problem. It looks like it works. I have not
> > > tested NAT-64 yet. Also I'd like to come up with test case, which
> > > will show the state check is still able to block invalid ICMP packet
> > > (invalid with respect to state).
> > > 
> > > The idea of fix is to keep icmp_dir in state as well. The icmp_dir
> > > indicates whether state got created by ICMP request or response.
> > > This is useful later in pf_icmp_state_lookup() to check whether
> > > ICMP request/response matches state direction.
> > > 
> > 
> > This feels slightly convoluted... check my diff out! (:
> 
> nice, I like your "XOR Magic!" comment.

(:

> Looks like I was trying to fix the other end...

And you were not wrong.

> your patch is minimalistic and correct as far as I can tell.
>

Well, not entirely (:  I did it while exploring the code and sent
out to provoke further discussion.  Today I've talked to reyk@ and
we think that it's better to go down a different road: make sure we
don't create states on reply packets in the first place.

Please consider the following: unless sloppy state tracking is used,
TCP states can only be set up by the first SYN packet (ok, ok, it's
because of "flags S/SA", but that is largely irrelevant nowadays
since "S/SA" is now the default and nobody is doing "flags any").

ICMP was made to adhere to a stricter set of rules and recently
I've added sloppy handling there so perhaps we should just prevent
state creation for replies (icmp_dir == PF_OUT)?  If that is not
what sysadmin wants he can always specify "keep state (sloopy)" and
move on with his/her life.

I've tested this with ICMP, ICMPv6 and NAT64 (slightly).  Any OKs?
Objections?

diff --git sys/net/pf.c sys/net/pf.c
index 39d5cb6..dbc8707 100644
--- sys/net/pf.c
+++ sys/net/pf.c
@@ -3201,10 +3201,15 @@ pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, 
struct pf_state **sm,
                        PF_TEST_ATTRIB((r->type && r->type != icmptype + 1),
                                TAILQ_NEXT(r, entries));
                        /* icmp only. type always 0 in other cases */
                        PF_TEST_ATTRIB((r->code && r->code != icmpcode + 1),
                                TAILQ_NEXT(r, entries));
+                       /* icmp only. don't create states on replies */
+                       PF_TEST_ATTRIB((r->keep_state && !state_icmp &&
+                           (r->rule_flag & PFRULE_STATESLOPPY) == 0 &&
+                           icmp_dir != PF_IN),
+                               TAILQ_NEXT(r, entries));
                        break;
 
                default:
                        break;
                }

Reply via email to