Summary: | [pf] pf crashes with a particular set of rules when first matching packet arrives | ||
---|---|---|---|
Product: | Base System | Reporter: | Eugene M. Zheganin <eugene> |
Component: | kern | Assignee: | freebsd-bugs (Nobody) <bugs> |
Status: | Closed Overcome By Events | ||
Severity: | Affects Only Me | CC: | kp |
Priority: | Normal | ||
Version: | 9.0-RELEASE | ||
Hardware: | Any | ||
OS: | Any |
Description
Eugene M. Zheganin
2012-01-23 10:40:06 UTC
Responsible Changed From-To: freebsd-bugs->freebsd-pf Over to maintainer(s). Hi, I have a vague suspicion on what is happening. Your description of the problem looks like if a packet processing in the kernel has entered an endless loop. Looking at pf_route() I see such possibility. From OpenBSD we have this protection against endless looping: if ((*m)->m_pkthdr.pf.routed++ > 3) { m0 = *m; *m = NULL; goto bad; } In our code this transforms to: if (pd->pf_mtag->routed++ > 3) { m0 = *m; *m = NULL; goto bad; } The root difference between storing the tag on mbuf and on pfdesc is that we lose pfdesc, and thus the tag, when we enter pf_test() recursively. And pf_route() does this recursion: if (oifp != ifp) { if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS) { goto bad; .... -- Totus tuus, Glebius. On Sun, Apr 15, 2012 at 11:10:03AM +0000, Gleb Smirnoff wrote: T> I have a vague suspicion on what is happening. Your description of T> the problem looks like if a packet processing in the kernel has entered T> an endless loop. T> T> Looking at pf_route() I see such possibility. From OpenBSD we have T> this protection against endless looping: T> T> if ((*m)->m_pkthdr.pf.routed++ > 3) { T> m0 = *m; T> *m = NULL; T> goto bad; T> } T> T> In our code this transforms to: T> T> if (pd->pf_mtag->routed++ > 3) { T> m0 = *m; T> *m = NULL; T> goto bad; T> } T> T> The root difference between storing the tag on mbuf and on pfdesc T> is that we lose pfdesc, and thus the tag, when we enter pf_test() T> recursively. And pf_route() does this recursion: T> T> if (oifp != ifp) { T> if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS) { T> goto bad; T> .... On second look I see that my suspicion may not be true. In the beginning of pf_test() we do pf_get_mtag() which preserves already present tag if there is one. -- Totus tuus, Glebius. For bugs matching the following criteria: Status: In Progress Changed: (is less than) 2014-06-01 Reset to default assignee and clear in-progress tags. Mail being skipped FreeBSD 9.0 is no longer supported. If this problem can be reproduced in 12.0 or 11.2 please re-open this bug. |