Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 Feb 1998 23:16:09 -0800 (PST)
From:      Archie Cobbs <archie@whistle.com>
To:        marcs@znep.com (Marc Slemko)
Cc:        jonny@coppe.ufrj.br, freebsd-hackers@freebsd.org
Subject:   Re: ipfw logs ports for fragments
Message-ID:  <199802090716.XAA06954@bubba.whistle.com>
In-Reply-To: <Pine.BSF.3.95.980208231009.18733W-100000@alive.znep.com> from Marc Slemko at "Feb 8, 98 11:15:57 pm"

next in thread | previous in thread | raw e-mail | index | archive | help
Marc Slemko writes:
> On Sun, 8 Feb 1998, Archie Cobbs wrote:
> 
> > Marc Slemko writes:
> > > If you don't explicitly tell ipfw to pass frags, it will not.  That will
> > > break some things, but is the safest way.
> > 
> > This is not correct.. ipfw will always block fragments whose offset
> > is one (only seen in attempts to subvert firewalls) but not ordinary
> > fragments... that would be a serious problem.
> 
> Ok, let me clarify that statement.
> 
> First, ipfw always blocks certain types of fragments that are used only to
> bypass firewalls. 
> 
> Second, it will block any fragment that _could_ match any deny rule even
> if it has incomplete information so it doesn't know that it _does_ match
> the rule.  Since the tcp header is normally only in the first fragment, if
> you block access to a specific port then ipfw can't know if subsequent
> fragments are to that port or not so it blocks them.  You need to add an
> explicit rule to allow it to pass such fragments if the risk is acceptable
> to you. 

After looking at the code, you're exactly right.. and this is a bug.

The way it works now is that the port range tests are simply not
applied to packets that have non-zero offsets. This means a rule
with a port range can possibly match fragments of packets it's not
intended for -- independently of whether it's an accept rule, deny
rule, divert rule, or whatever. In other words, port range rules
match non-zero offset fragments too liberally.

If it's an accept rule, this is OK -- because if the packet is
really supposed to be rejected, then the first fragement always
will be, so the entire packet is lost, even if you accidentally
pass other fragments of it. Matching too liberally here is OK.

However, if it's a deny rule, then you may be unexpectedly blocking
some framgents of packets (and therefore the entire packet), even
if these packets' ports don't fall in the range specified by
the deny rule. Oops. What you want to do here instead is match too
conservatively and NOT match questionable fragments.

In the case of divert, count, skipto, etc. rules... what's the
right answer?? There isn't one unless the kernel keeps track of
all the fragments flying by, and matches them up with their
corresponding initial fragments, and whether that initial fragment
matched or not.. i.e., keeping a lot of extra information around.

Recommendation:

- At the least, a note should be added to the man page for this.

- Going further: for accept and deny rules we can special case
  the rule and do (very close to) the right thing as discussed above.

- Going still further: for divert rules, if the packet matches we
  have to assemble all the fragments anyway, so we're keeping
  most of the state we need to keep already. Once we get the whole
  packet, we determine whether or not to divert it or forward it.

- Going all the way: extend above divert approach to all rules that
  match port ranges: for any fragments of packets that *might* match
  a port range rule, reassemble the entire packet before applying
  the rule.

Come to think of it, the latter approach would not be that hard
since the kernel is doing this already for locally routed packets,
that is, reassembling packet fragments in a fragment queue. Moreover,
"most" packets don't get fragmentized. It would spread more ugliness
into ip_input.c, but at least the behavoir of the ipfw code would
then be semantically correct...

-Archie

___________________________________________________________________________
Archie Cobbs   *   Whistle Communications, Inc.  *   http://www.whistle.com

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199802090716.XAA06954>