From nobody Wed Apr 02 19:12:23 2025 X-Original-To: dev-commits-src-main@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 4ZSZHq5KrYz5rSdV; Wed, 02 Apr 2025 19:12:23 +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 "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4ZSZHq4QPKz3JNB; Wed, 02 Apr 2025 19:12:23 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1743621143; 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=gVokESxDeLPoDtopB99ZkN+sfzBW9Skqadhdy9p8ALw=; b=hrvF0hebJkuWBWEmfwWetilORRnwLphBOiRyJ+MVArzXOqAqfa3EXTGkH1POsiQKQWUXi1 zdicjVBtcjaQrhjh/J0nZj2S3mPhK/Pv8oXe512lMrV20FtEqZ74unyRauk1gbnBewrniO ERbvx0v5YVpXFj4iCGraDlO0Gs3gEdtuAk37dYvsEFcBQ6othg1gbeG0A7vZh1tHSdytC+ bhpQRzpUbRSTA3Cp6q2KB8KlCnIGa3+LcT5JlhcEegdnO4zjoecqZJRKr/yxb+O3xapTp9 OOmg8PR4Xc7raVjLdiAQARaqwS1CdZvmgs2DZQAGZnrSCyNoYIoyTya4pFc77Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1743621143; a=rsa-sha256; cv=none; b=j+hb1CHeQc4gEeo0lwJCc7h2YzGVcR7Ej4s3wWVY7b7sH6nJslWyah2Xg84LHwhh2gzRKf 2641Iz0K47pByGL8Scq2qgIrPVid2gbtOyXpO3SurpiCRCjHNqWojvYdkB0rBD5Zqoer9w lNSAE84MrlBjxaWkuIRnLTQV7kScC7D5tPIgrij0i8ct5/WVek9h0lo1n9NubWWmo4KOwt u7s3kmcmDcFWOFaye3i7XradbZk/GZv81sv3yMtnIRRKCxfOQbDhWG0aj7QT0tn//wQW1Z y+wjyrcP+igig4JZoA5icNNhqv/NMUcnSM5KEhOOcfxUWIxaCLx2DtUgJDr/2A== 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=1743621143; 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=gVokESxDeLPoDtopB99ZkN+sfzBW9Skqadhdy9p8ALw=; b=ockn1NxjxkIV2K4hvkZgBpUujsD1cqfyt2x7/Vo/utODmEfi7hQ2ljywE5nbxruCiM382e G8MKZxrqg+wtuPTQA9QhhpDnT32OcmVId2BwiDSN3zyU5P6YSSQQ6FakgUaPo+EvRGw7fU rO22jsDi3m2vlxJTJtTKh1vmrB8EHHMEZSIN/SzJCscj4zbf3Z2cyBRAnFBAu1ETnLnQ/p HApEJpGLHnT/Y/hCfwS/LKKFHhgLpy7cnIPfaS8Uwpp1y6FvyyjY44th6N3Kmz5b3sY8GY tWc6o0HPPa3km89hvehautnPmH8IKIpTdBXulrG+goiyrWFNYkOOP0kHxmdfwA== 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 4ZSZHq3klxzD01; Wed, 02 Apr 2025 19:12:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 532JCNYZ010035; Wed, 2 Apr 2025 19:12:23 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 532JCNlU010031; Wed, 2 Apr 2025 19:12:23 GMT (envelope-from git) Date: Wed, 2 Apr 2025 19:12:23 GMT Message-Id: <202504021912.532JCNlU010031@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: 58164dcb55d6 - main - pfctl: fix recursive printing of NAT rules List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@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/main X-Git-Reftype: branch X-Git-Commit: 58164dcb55d62ca73b5e550b8344bf61e2d8a47a Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=58164dcb55d62ca73b5e550b8344bf61e2d8a47a commit 58164dcb55d62ca73b5e550b8344bf61e2d8a47a Author: Kristof Provost AuthorDate: 2025-04-02 16:04:46 +0000 Commit: Kristof Provost CommitDate: 2025-04-02 19:11:47 +0000 pfctl: fix recursive printing of NAT rules pfctl_show_nat() is called recursively to print nat anchors. This passes the anchor path, but this path was modified by pfctl_show_nat(), leading to issues printing the anchors. Make a copy of the path ('npath') before we modify it. Ensure we do this correctly by sprinking in 'const', and add a test case to verify that we do now print things correctly. Reported by: Thomas Pasqualini MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") --- sbin/pfctl/pfctl.c | 33 +++++++++++++++--------------- tests/sys/netpfil/pf/anchor.sh | 46 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 16 deletions(-) diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 7e06f4136686..1c5b7f5e1fc0 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -93,12 +93,12 @@ int pfctl_load_hostid(struct pfctl *, u_int32_t); int pfctl_load_reassembly(struct pfctl *, u_int32_t); int pfctl_load_syncookies(struct pfctl *, u_int8_t); int pfctl_get_pool(int, struct pfctl_pool *, u_int32_t, u_int32_t, int, - char *, int); + const char *, int); void pfctl_print_eth_rule_counters(struct pfctl_eth_rule *, int); void pfctl_print_rule_counters(struct pfctl_rule *, int); int pfctl_show_eth_rules(int, char *, int, enum pfctl_show, char *, int, int); int pfctl_show_rules(int, char *, int, enum pfctl_show, char *, int, int); -int pfctl_show_nat(int, char *, int, char *, int, int); +int pfctl_show_nat(int, const char *, int, char *, int, int); int pfctl_show_src_nodes(int, int); int pfctl_show_states(int, const char *, int); int pfctl_show_status(int, int); @@ -956,7 +956,7 @@ pfctl_id_kill_states(int dev, const char *iface, int opts) int pfctl_get_pool(int dev, struct pfctl_pool *pool, u_int32_t nr, - u_int32_t ticket, int r_action, char *anchorname, int which) + u_int32_t ticket, int r_action, const char *anchorname, int which) { struct pfioc_pooladdr pp; struct pf_pooladdr *pa; @@ -1438,7 +1438,7 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format, } int -pfctl_show_nat(int dev, char *path, int opts, char *anchorname, int depth, +pfctl_show_nat(int dev, const char *path, int opts, char *anchorname, int depth, int wildcard) { struct pfctl_rules_info ri; @@ -1461,16 +1461,17 @@ pfctl_show_nat(int dev, char *path, int opts, char *anchorname, int depth, p[0] = '\0'; } + if ((npath = calloc(1, MAXPATHLEN)) == NULL) + errx(1, "pfctl_rules: calloc"); + if (anchorname[0] == '/') { - if ((npath = calloc(1, MAXPATHLEN)) == NULL) - errx(1, "pfctl_rules: calloc"); snprintf(npath, MAXPATHLEN, "%s", anchorname); } else { - if (path[0]) - snprintf(&path[len], MAXPATHLEN - len, "/%s", anchorname); + snprintf(npath, MAXPATHLEN, "%s", path); + if (npath[0]) + snprintf(&npath[len], MAXPATHLEN - len, "/%s", anchorname); else - snprintf(&path[len], MAXPATHLEN - len, "%s", anchorname); - npath = path; + snprintf(&npath[len], MAXPATHLEN - len, "%s", anchorname); } /* @@ -1500,12 +1501,12 @@ pfctl_show_nat(int dev, char *path, int opts, char *anchorname, int depth, INDENT(depth, !(opts & PF_OPT_VERBOSE)); printf("}\n"); } - path[len] = '\0'; + npath[len] = '\0'; return (0); } for (i = 0; i < 3; i++) { - ret = pfctl_get_rules_info_h(pfh, &ri, nattype[i], path); + ret = pfctl_get_rules_info_h(pfh, &ri, nattype[i], npath); if (ret != 0) { warnc(ret, "DIOCGETRULES"); return (-1); @@ -1513,19 +1514,19 @@ pfctl_show_nat(int dev, char *path, int opts, char *anchorname, int depth, for (nr = 0; nr < ri.nr; ++nr) { INDENT(depth, !(opts & PF_OPT_VERBOSE)); - if ((ret = pfctl_get_rule_h(pfh, nr, ri.ticket, path, + if ((ret = pfctl_get_rule_h(pfh, nr, ri.ticket, npath, nattype[i], &rule, anchor_call)) != 0) { warnc(ret, "DIOCGETRULE"); return (-1); } if (pfctl_get_pool(dev, &rule.rdr, nr, - ri.ticket, nattype[i], path, PF_RDR) != 0) + ri.ticket, nattype[i], npath, PF_RDR) != 0) return (-1); if (pfctl_get_pool(dev, &rule.nat, nr, - ri.ticket, nattype[i], path, PF_NAT) != 0) + ri.ticket, nattype[i], npath, PF_NAT) != 0) return (-1); if (pfctl_get_pool(dev, &rule.route, nr, - ri.ticket, nattype[i], path, PF_RT) != 0) + ri.ticket, nattype[i], npath, PF_RT) != 0) return (-1); if (dotitle) { diff --git a/tests/sys/netpfil/pf/anchor.sh b/tests/sys/netpfil/pf/anchor.sh index 40e8354a2343..463cd4d475e3 100644 --- a/tests/sys/netpfil/pf/anchor.sh +++ b/tests/sys/netpfil/pf/anchor.sh @@ -316,6 +316,51 @@ counter_cleanup() pft_cleanup } +atf_test_case "nat" "cleanup" +nat_head() +{ + atf_set descr 'Test nested nat anchors' + atf_set require.user root +} + +nat_body() +{ + pft_init + + epair=$(vnet_mkepair) + vnet_mkjail alcatraz ${epair}a + + ifconfig ${epair}b 192.0.2.2/24 up + jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up + + # Sanity check + atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 + + jexec alcatraz pfctl -e + pft_set_rules alcatraz \ + "nat-anchor \"foo/*\"" \ + "pass" + + echo "nat log on ${epair}a inet from 192.0.2.0/24 to any port = 53 -> 192.0.2.1" \ + | jexec alcatraz pfctl -a "foo/bar" -g -f - + echo "rdr on ${epair}a proto tcp to port echo -> 127.0.0.1 port echo" \ + | jexec alcatraz pfctl -a "foo/baz" -g -f - + + jexec alcatraz pfctl -sn -a "*" + jexec alcatraz pfctl -sn -a "foo/bar" + jexec alcatraz pfctl -sn -a "foo/baz" + + atf_check -s exit:0 -o match:"nat log on epair0a inet from 192.0.2.0/24 to any port = domain -> 192.0.2.1" \ + jexec alcatraz pfctl -sn -a "*" + atf_check -s exit:0 -o match:"rdr on epair0a inet proto tcp from any to any port = echo -> 127.0.0.1 port 7" \ + jexec alcatraz pfctl -sn -a "*" +} + +nat_cleanup() +{ + pft_cleanup +} + atf_init_test_cases() { atf_add_test_case "pr183198" @@ -326,4 +371,5 @@ atf_init_test_cases() atf_add_test_case "quick" atf_add_test_case "quick_nested" atf_add_test_case "counter" + atf_add_test_case "nat" }