Date: Tue, 17 Apr 2012 10:06:15 +0200 From: =?ISO-8859-1?Q?Ermal_Lu=E7i?= <eri@freebsd.org> To: Gleb Smirnoff <glebius@freebsd.org> Cc: freebsd-pf@freebsd.org Subject: Re: kern/164402: [pf] pf crashes with a particular set of rules when first matching packet arrives Message-ID: <CAPBZQG2Tjg36GNCBetRZ20FhQnL1sK9i_-oQDDb97bcb4N=sLA@mail.gmail.com> In-Reply-To: <20120416185949.GC92286@FreeBSD.org> References: <201204151200.q3FC0LT5085161@freefall.freebsd.org> <20120416185949.GC92286@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
2012/4/16 Gleb Smirnoff <glebius@freebsd.org>: > On Sun, Apr 15, 2012 at 12:00:21PM +0000, Gleb Smirnoff wrote: > T> =A0On Sun, Apr 15, 2012 at 11:10:03AM +0000, Gleb Smirnoff wrote: > T> =A0T> =A0 =A0I have a vague suspicion on what is happening. Your descr= iption of > T> =A0T> =A0the problem looks like if a packet processing in the kernel h= as entered > T> =A0T> =A0an endless loop. > T> =A0T> > T> =A0T> =A0 =A0Looking at pf_route() I see such possibility. From OpenBS= D we have > T> =A0T> =A0this protection against endless looping: > T> =A0T> > T> =A0T> =A0 =A0 =A0 =A0 =A0if ((*m)->m_pkthdr.pf.routed++ > 3) { > T> =A0T> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0m0 =3D *m; > T> =A0T> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*m =3D NULL; > T> =A0T> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto bad; > T> =A0T> =A0 =A0 =A0 =A0 =A0} > T> =A0T> > T> =A0T> =A0In our code this transforms to: > T> =A0T> > T> =A0T> =A0 =A0 =A0 =A0 =A0if (pd->pf_mtag->routed++ > 3) { > T> =A0T> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0m0 =3D *m; > T> =A0T> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*m =3D NULL; > T> =A0T> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto bad; > T> =A0T> =A0 =A0 =A0 =A0 =A0} > T> =A0T> > T> =A0T> =A0The root difference between storing the tag on mbuf and on pf= desc > T> =A0T> =A0is that we lose pfdesc, and thus the tag, when we enter pf_te= st() > T> =A0T> =A0recursively. And pf_route() does this recursion: > T> =A0T> > T> =A0T> =A0 =A0 =A0 =A0 =A0if (oifp !=3D ifp) { > T> =A0T> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (pf_test(PF_OUT, ifp, &m0,= NULL) !=3D PF_PASS) { > T> =A0T> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto bad; > T> =A0T> =A0 =A0 =A0 =A0 =A0.... > T> > T> =A0On second look I see that my suspicion may not be true. In the > T> =A0beginning of pf_test() we do pf_get_mtag() which preserves already > T> =A0present tag if there is one. > > Further investigation showed that problem exist when route applied > ends in lo0, and packet passes to if_simloop(). There all mtags are > stripped from the mbuf, including the pf mtag. Then packet is again > processed by ip_input() again entering pf(4), if it again matches > a routing rule, then we got an endless loop. > > We can try to fix this applying MTAG_PERSISTENT to the pf(4) tag id. > That seems like the best fix for this case. > -- > Totus tuus, Glebius. > _______________________________________________ > freebsd-pf@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-pf > To unsubscribe, send any mail to "freebsd-pf-unsubscribe@freebsd.org" --=20 Ermal
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAPBZQG2Tjg36GNCBetRZ20FhQnL1sK9i_-oQDDb97bcb4N=sLA>