On Thu, Jun 16, 2011 at 11:18:30PM +0200, Claudio Jeker wrote:
> On Wed, Jun 15, 2011 at 11:06:16PM -0400, Kenneth R Westerback wrote:
> > On Wed, Jun 15, 2011 at 09:50:51PM -0400, Kenneth R Westerback wrote:
> > > On Tue, Jun 14, 2011 at 10:23:36PM +0200, Claudio Jeker wrote:
> > > > On Wed, Jun 08, 2011 at 09:53:24AM +0200, Claudio Jeker wrote:
> > > > > Next step on my quest to unify pf_test and pf_test6.
> > > > > Move the fragment handling and some other protocol specific tests into
> > > > > pf_setup_pdesc(). IPv6 already does this mostly but only IPv4 did 
> > > > > not. So
> > > > > this diff brings that more into sync. It also includes some additional
> > > > > cleanups.
> > > > > 
> > > > > Works for me but needs some more testing.
> > > > 
> > > > New version with fixes found by bluhm@ (mostly make sure that the right
> > > > header and mbufs are used in all cases).
> > > > 
> > > > -- 
> > > > :wq Claudio
> > > 
> > > Blows up REAL good on my 6xamd64 box. Within a minute or two.
> > > 
> > > I put some debug in and pf_scrub() is being passed a NULL 'm' parameter
> > > from pf_test(). Hand transcribed trace:
> > > 
> > > pf_scrub()+0x12
> > > pf_test()+0x93b
> > > ipv4_input()+0x22a
> > > ipintr()+0x51
> > > netintr()+0xda
> > > softintr_dispatch()+0x5d
> > > Xsoftnet()+0x2d
> > > 
> > > This box is my nfs server and is using the default pf.conf file as far
> > > as I know. Also blew up on my firewall as soon as traffic started
> > > transitting it. Same trace as far as I can see.
> > > 
> > > .... Ken
> > > 
> > 
> > panic'ing my way along the stack I find that the problem starts in
> > pf_reassemble(), when the 'if (!pf_isfull_fragment(frag))' test
> > leaves m0 as NULL and returns PF_PASS to pf_normalize_ip(). *m0 is
> > tested and found to be NULL, so pf_normalize_ip() returns PF_PASS to
> > pf_setup_pdesc(). Where *m0 is tested for NULL and causes *action to
> > be set to PF_PASS and pf_setup_pdesc() to return -1 to pf_test. m is
> > set to *m0 (i.e. NULL) and then pf_test goto's done:. action is PF_PASS
> > and 'if (s)' fails so control passes to the first statement of the else,
> > which is a pf_scrub() call with m being NULL. Boom.
> > 
> 
> Yes, very good analysis. I came to the same conclusion. I do not
> understand why we do the goto done; case for PF_PASS in case of a
> pf_setup_pdesc() failure. Since in that case *m0 is NULL and so we can
> just return directly from there. I changed my diff to do exactly that. On
> further inspection I think there is no other case where pf_setup_pdesc()
> returns -1 but action is set to PF_PASS. IMO this is a lot saver then
> trying to execute all that code after the done: label.
> 
> New diff below
> -- 
> :wq Claudio

This doesn't immediately crash my nfs server like the original did. I'll
let you know if anything else goes wrong. :-)

.... Ken

Reply via email to