From nobody Sat Oct 07 15:36:41 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4S2qCY4g1yz4wkj3; Sat, 7 Oct 2023 15:36:41 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4S2qCY4Fk9z4v45; Sat, 7 Oct 2023 15:36:41 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1696693001; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=w8BCtbtN7/ZJzrFOugZ91IphoZar7i45nsdAcxFINjk=; b=Z79BN01fPTlgffflKzGpuhPRlcJKUTw3DWbznOhx28dszn9NQkmnTCmBxtsx7XBbxLyqez oYoePBcRaexQcAx1gLBY17L/ARrzUwLACtoAYZHyhnqkujpW5jiv1Hlw3l0QwNqC94U1Cj uH187aIVmuOnGNeHCJV9rsp5wr9GhoxnzbzaPa20qjsre1sYgclCj1Qe76fKZA0WaJF6jG C3ld9KBLOZCjhJIuSyi8l3+kpx3Ny/lLFRe/CJYtQlckM0O3ZaNlCSWcj0A/PXndS6ainn nK6frgHdq9DSC42iRr43rIObak5I3ANo/CaNpFEuejKMrHx2RIIJiuYqk/ooBA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1696693001; a=rsa-sha256; cv=none; b=mmnIV0WwRkJ1v6YzSD+rNrWI1p19QfAOKSrM3EdcGBpDxiggbk/EjBlBzCSqKvxjdg67JL aBaHwiEQ8HFpk9nkiUsNt65abrVWft7C719kB3TwgTRm5ZEJUkZa2TwGi5p0LChSWu2HZv O+qYaTnkoLeUOOXJtLFPkFcJtTx/VUiVHOL58E6Et6/DTwiLHrn6ePgO/uefECbnSAuZqH xehxnuMrJ8j5bFyO9zfslQUlqUBU0T7yf2ZXLmrorgvOOgsrvaApNkPjzVd5k7j9iye63S d1F/zxLa7yX6XcnKlOtEIw95uxpY8dFRnHWbqp/T/TMcultGGT5maoDBxIr2JQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1696693001; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=w8BCtbtN7/ZJzrFOugZ91IphoZar7i45nsdAcxFINjk=; b=MN6t3AYOH64Svp21Z2Hc4e5HLJmANux6XqFuvL+pLCqsiDkdgngKR68iRhZECfArYKko7P hBniS0jzpvgusIou0GlBanNq9m5mNyw98gNZmIQetT4TtpnD2tLhFkktwZjBkxhIuYS1Au TAkkuQrRO+l8f+Jzxiv+/plYsUYmmOOvUwXawyZq3FWjFbeSNNsSbV8TI2J2yoqPnOa1Yi 3DzvO7XAPtSlZ+77isCHLgEC9qLw/Ygh69fszrBKcCyjNSvALDn/YunZphnkl+BuFSN8Ls PZawY/W3ndd6NKbswdMqtfDah2VyeYLeG1vpPEiSuYEZNBdYB+78FxafRX/nDg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4S2qCY3BL0zbZC; Sat, 7 Oct 2023 15:36:41 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 397FafeJ003857; Sat, 7 Oct 2023 15:36:41 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 397Fafi9003854; Sat, 7 Oct 2023 15:36:41 GMT (envelope-from git) Date: Sat, 7 Oct 2023 15:36:41 GMT Message-Id: <202310071536.397Fafi9003854@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kristof Provost Subject: git: f69181e9de1b - stable/14 - pf: cope with missing rpool.cur List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: f69181e9de1b021f4689ce50b420f9c694268ec8 Auto-Submitted: auto-generated The branch stable/14 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=f69181e9de1b021f4689ce50b420f9c694268ec8 commit f69181e9de1b021f4689ce50b420f9c694268ec8 Author: Kristof Provost AuthorDate: 2023-10-03 15:11:44 +0000 Commit: Kristof Provost CommitDate: 2023-10-07 07:39:04 +0000 pf: cope with missing rpool.cur If we're evaluating a pfsync'd state (and have different rules on both ends) our state may point to the default rule, which does not have rpool.cur set. As a result we can end up dereferencing a NULL pointer. Explicitly check for this when we try to re-construct the route-to interface. Also add a test case which can trigger this issue. MFC after: 3 days See also: https://redmine.pfsense.org/issues/14804 Sponsored by: Rubicon Communications, LLC ("Netgate") (cherry picked from commit 74c2461386ea5eeb41e674df6b16a44b0509a882) --- sys/netpfil/pf/pf.c | 9 ++-- tests/sys/netpfil/pf/pfsync.sh | 96 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 4 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 3e1c8d32add9..fae0bd2854f9 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -6978,7 +6978,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, } else { ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; /* If pfsync'd */ - if (ifp == NULL) + if (ifp == NULL && r->rpool.cur != NULL) ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; PF_STATE_UNLOCK(s); @@ -7035,9 +7035,10 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, s->rt_addr.v4.s_addr; ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; /* If pfsync'd */ - if (ifp == NULL) + if (ifp == NULL && r->rpool.cur != NULL) { ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; + } PF_STATE_UNLOCK(s); } @@ -7191,7 +7192,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, } else { ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; /* If pfsync'd */ - if (ifp == NULL) + if (ifp == NULL && r->rpool.cur != NULL) ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; PF_STATE_UNLOCK(s); @@ -7249,7 +7250,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, &s->rt_addr, AF_INET6); ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; /* If pfsync'd */ - if (ifp == NULL) + if (ifp == NULL && r->rpool.cur != NULL) ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; } diff --git a/tests/sys/netpfil/pf/pfsync.sh b/tests/sys/netpfil/pf/pfsync.sh index d62cdddd504a..91c7b8410a08 100644 --- a/tests/sys/netpfil/pf/pfsync.sh +++ b/tests/sys/netpfil/pf/pfsync.sh @@ -825,6 +825,101 @@ basic_ipv6_cleanup() pfsynct_cleanup } +atf_test_case "route_to" "cleanup" +route_to_head() +{ + atf_set descr 'Test route-to with default rule' + atf_set require.user root + atf_set require.progs scapy +} + +route_to_body() +{ + pfsynct_init + + epair_sync=$(vnet_mkepair) + epair_one=$(vnet_mkepair) + epair_two=$(vnet_mkepair) + epair_out_one=$(vnet_mkepair) + epair_out_two=$(vnet_mkepair) + + vnet_mkjail one ${epair_one}a ${epair_sync}a ${epair_out_one}a + vnet_mkjail two ${epair_two}a ${epair_sync}b ${epair_out_two}a + + # pfsync interface + jexec one ifconfig ${epair_sync}a 192.0.2.1/24 up + jexec one ifconfig ${epair_one}a 198.51.100.1/24 up + jexec one ifconfig ${epair_out_one}a 203.0.113.1/24 up + jexec one ifconfig ${epair_out_one}a name outif + jexec one sysctl net.inet.ip.forwarding=1 + jexec one arp -s 203.0.113.254 00:01:02:03:04:05 + jexec one ifconfig pfsync0 \ + syncdev ${epair_sync}a \ + maxupd 1 \ + up + + jexec two ifconfig ${epair_sync}b 192.0.2.2/24 up + jexec two ifconfig ${epair_two}a 198.51.100.2/24 up + jexec two ifconfig ${epair_out_two}a 203.0.113.2/24 up + #jexec two ifconfig ${epair_out_two}a name outif + jexec two sysctl net.inet.ip.forwarding=1 + jexec two arp -s 203.0.113.254 00:01:02:03:04:05 + jexec two ifconfig pfsync0 \ + syncdev ${epair_sync}b \ + maxupd 1 \ + up + + # Enable pf! + jexec one pfctl -e + pft_set_rules one \ + "set skip on ${epair_sync}a" \ + "pass out route-to (outif 203.0.113.254)" + jexec two pfctl -e + + # Make sure we have different rulesets so the synced state is associated with + # V_pf_default_rule + pft_set_rules two \ + "set skip on ${epair_sync}b" \ + "pass out route-to (outif 203.0.113.254)" \ + "pass out proto tcp" + + ifconfig ${epair_one}b 198.51.100.254/24 up + ifconfig ${epair_two}b 198.51.100.253/24 up + route add -net 203.0.113.0/24 198.51.100.1 + ifconfig ${epair_two}b up + ifconfig ${epair_out_one}b up + ifconfig ${epair_out_two}b up + + atf_check -s exit:0 env PYTHONPATH=${common_dir} \ + ${common_dir}/pft_ping.py \ + --sendif ${epair_one}b \ + --fromaddr 198.51.100.254 \ + --to 203.0.113.254 \ + --recvif ${epair_out_one}b + + # Allow time for sync + ifconfig ${epair_one}b inet 198.51.100.254 -alias + route del -net 203.0.113.0/24 198.51.100.1 + route add -net 203.0.113.0/24 198.51.100.2 + + sleep 2 + + # Now try to trigger the state on the other pfsync member + env PYTHONPATH=${common_dir} \ + ${common_dir}/pft_ping.py \ + --sendif ${epair_two}b \ + --fromaddr 198.51.100.254 \ + --to 203.0.113.254 \ + --recvif ${epair_out_two}b + + true +} + +route_to_cleanup() +{ + pfsynct_cleanup +} + atf_init_test_cases() { atf_add_test_case "basic" @@ -837,4 +932,5 @@ atf_init_test_cases() atf_add_test_case "timeout" atf_add_test_case "basic_ipv6_unicast" atf_add_test_case "basic_ipv6" + atf_add_test_case "route_to" }