From owner-freebsd-pf@FreeBSD.ORG Sun Apr 15 11:51:29 2012 Return-Path: Delivered-To: freebsd-pf@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6CCE21065670; Sun, 15 Apr 2012 11:51:29 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from cell.glebius.int.ru (glebius.int.ru [81.19.64.117]) by mx1.freebsd.org (Postfix) with ESMTP id DB3158FC21; Sun, 15 Apr 2012 11:51:25 +0000 (UTC) Received: from cell.glebius.int.ru (localhost [127.0.0.1]) by cell.glebius.int.ru (8.14.5/8.14.5) with ESMTP id q3FBpOWf081021; Sun, 15 Apr 2012 15:51:24 +0400 (MSK) (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by cell.glebius.int.ru (8.14.5/8.14.5/Submit) id q3FBpOow081020; Sun, 15 Apr 2012 15:51:24 +0400 (MSK) (envelope-from glebius@FreeBSD.org) X-Authentication-Warning: cell.glebius.int.ru: glebius set sender to glebius@FreeBSD.org using -f Date: Sun, 15 Apr 2012 15:51:24 +0400 From: Gleb Smirnoff To: freebsd-pf@FreeBSD.org Message-ID: <20120415115124.GO9391@FreeBSD.org> References: <201204151110.q3FBA3Fr034331@freefall.freebsd.org> MIME-Version: 1.0 Content-Type: text/plain; charset=koi8-r Content-Disposition: inline In-Reply-To: <201204151110.q3FBA3Fr034331@freefall.freebsd.org> User-Agent: Mutt/1.5.21 (2010-09-15) Cc: bug-followup@FreeBSD.org Subject: Re: kern/164402: [pf] pf crashes with a particular set of rules when first matching packet arrives X-BeenThere: freebsd-pf@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Technical discussion and general questions about packet filter \(pf\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 Apr 2012 11:51:29 -0000 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.