Skip site navigation (1)Skip section navigation (2)
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>