From nobody Wed Oct 28 20:41:25 2026 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 4jFK5l3ZPtz6x6Xh for ; Wed, 28 Oct 2026 20:41:31 +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) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4jFK5l0kZYz4b02 for ; Wed, 28 Oct 2026 20:41:31 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793220091; 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=ykWAURfed7D6kKKoOJaUWGTpysCK1T5cR+BsLk6rBJc=; b=yE4euAUqo5ov7gEb1ykyPqa24t4edYiyYpIW0Dmk2AwSeTVYb1CPCbrk08aRxYWa4xDxzv UEtOsge4FTQZbN99Ph+zCS/kVfbreqG8IIKMcHYYSHydWARFOU1Bu+xHekZJfEkV+NFAwF oME4BMGgkzroIjKMIO7glKLHKbX3VGmzVaAvVa+jVEd9tD8z71odgaIDDBxgwlDcQ4l5XR 11yVH6UO2DikzRMf0HkvodQD/bfrG6dUQ6xWbQqXUW7+Hepf9gc65R39Tu/XZR5jwOEkXT rk7PvRbYqwfqF+bq1Y85t9BG8Wnpj2Bgt/xUlJJ79dfodMnT8KVENoDscFtLfQ== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1793220091; b=REL+iFBjBA5T/vGj3Ic68Trvb3sJhVCnR8p51I8VVqejNKg7NQ24tDw/YEGUwQmGtcV07/ pgwzTjJLqgaoqx7cKaoRbvX3NFxdC6Am6PIuKWBlpmm6njiGUXr2QWvXbWAY/T7/jFZZ7e DL6ZR2mjwgZDiIZMqENNZXlb42rlvE/c4mUUIymUf+/1HTHcXSBQjiqpoisKcHx9MGP6zM HHXnLAu56sj32Antgw8BKvSfoCtJqGyVAAmfBfdtSBT5FW4n4FEj9IHpuPENe80BIrKkLU ddGB0kAYSt9YJMRXHiQceX56ykkZNt4oIsJxZy3RIIyPy2+ojw0Mw8/BGkOkcg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793220091; 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=ykWAURfed7D6kKKoOJaUWGTpysCK1T5cR+BsLk6rBJc=; b=RhleqwVDvAfXhBG2BRB5a97YiwxoAdhDqIbnlQKMKr7GtEUTUaeCVzSAcbKQpGdrnnuNKS KkTjbOChSCB3p27UmnMbbrgRzom38z8HrE8DWmycazAtDTQkvSoPqo4023dYaab77iHUxu dP87trTRwlRoulAG03aPnsEvB67b0mdWkxRGIzHu9AVHChFIGvkMbeV8setn04mNQDikwz iycCK1QT3NeZZlthywsq0DCNCG5fIkLSRpjXfFO1orWKNXFcE3v//lnIOEXnWZzjtM4aNy dohkst3Tkp/0LTK0/Wl3PqH5PzQGsSKtq+VfERoKZ+32+0C4tJ/11Pfvh/qb0A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4jFK5l0N5lz1N5m for ; Wed, 28 Oct 2026 20:41:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1e6fc by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 28 Oct 2026 20:41:25 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: R. Christian McDonald Subject: git: 1ecbabf77217 - stable/14 - pf: do not loop on an address that is cleared twice in pfr_clr_astats() List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: Commit messages for all branches of the src repository List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rcm X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 1ecbabf7721788f680ba3d3f2a5fc9e1b8ecb96e Auto-Submitted: auto-generated Date: Wed, 28 Oct 2026 20:41:25 +0000 Message-Id: <6ae25df5.1e6fc.435b9018@gitrepo.freebsd.org> The branch stable/14 has been updated by rcm: URL: https://cgit.FreeBSD.org/src/commit/?id=1ecbabf7721788f680ba3d3f2a5fc9e1b8ecb96e commit 1ecbabf7721788f680ba3d3f2a5fc9e1b8ecb96e Author: R. Christian McDonald AuthorDate: 2026-09-29 00:07:22 +0000 Commit: R. Christian McDonald CommitDate: 2026-10-28 20:38:02 +0000 pf: do not loop on an address that is cleared twice in pfr_clr_astats() pfr_clr_astats() looks up each address it is given and inserts the entry it finds at the head of a work queue. If the same address is given more than once, the entry is inserted twice and the second insertion makes it its own successor. pfr_clstats_kentries() then walks the queue forever, with the rules lock held for writing, so packet processing and every other pf operation in that vnet stop as well. To reproduce: pfctl -e pfctl -t foo -T add 192.0.2.1 pfctl -t foo -T zero 192.0.2.1 192.0.2.1 Do as pfr_del_addrs() does: clear pfrke_mark on the entries named, then queue an entry only the first time it is seen. An address given more than once is cleared, and counted, once. Validate all addresses before any entry is touched. Add a regression test. Reviewed by: kp Approved by: kp (mentor) MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D60103 (cherry picked from commit ee05a360b02e4615d50eae7cababd2ab2d05d488) --- sys/netpfil/pf/pf_table.c | 11 +++++++++-- tests/sys/netpfil/pf/table.sh | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/sys/netpfil/pf/pf_table.c b/sys/netpfil/pf/pf_table.c index 3004609e1702..a064aca5bebe 100644 --- a/sys/netpfil/pf/pf_table.c +++ b/sys/netpfil/pf/pf_table.c @@ -653,16 +653,23 @@ pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size, kt = pfr_lookup_table(tbl); if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE)) return (ESRCH); - SLIST_INIT(&workq); for (i = 0, ad = addr; i < size; i++, ad++) { if (pfr_validate_addr(ad)) senderr(EINVAL); p = pfr_lookup_addr(kt, ad, 1); + if (p != NULL) + p->pfrke_mark = 0; + } + SLIST_INIT(&workq); + for (i = 0, ad = addr; i < size; i++, ad++) { + p = pfr_lookup_addr(kt, ad, 1); if (flags & PFR_FLAG_FEEDBACK) { ad->pfra_fback = (p != NULL) ? PFR_FB_CLEARED : PFR_FB_NONE; } - if (p != NULL) { + /* An address given more than once is cleared once. */ + if (p != NULL && !p->pfrke_mark) { + p->pfrke_mark = 1; SLIST_INSERT_HEAD(&workq, p, pfrke_workq); xzero++; } diff --git a/tests/sys/netpfil/pf/table.sh b/tests/sys/netpfil/pf/table.sh index f655463f3c03..728b82e7cd29 100644 --- a/tests/sys/netpfil/pf/table.sh +++ b/tests/sys/netpfil/pf/table.sh @@ -194,6 +194,39 @@ zero_one_cleanup() pft_cleanup } +atf_test_case "zero_twice" "cleanup" +zero_twice_head() +{ + atf_set descr 'Test zeroing an address that is given twice' + atf_set require.user root + atf_set timeout 30 +} + +zero_twice_body() +{ + pft_init + + vnet_mkjail alcatraz + jexec alcatraz pfctl -e + + pft_set_rules alcatraz \ + "table counters { 192.0.2.1, 192.0.2.3 }" \ + "pass in from to any" + + # This used to hang the kernel with the rules lock held: + # pfr_clr_astats() put the entry on its work queue twice. + atf_check -s exit:0 -e "match:1/2 addresses cleared." \ + jexec alcatraz pfctl -t foo -T zero 192.0.2.1 192.0.2.1 + atf_check -s exit:0 -e "match:2/4 addresses cleared." \ + jexec alcatraz pfctl -t foo -T zero 192.0.2.3 192.0.2.1 \ + 192.0.2.3 192.0.2.5 +} + +zero_twice_cleanup() +{ + pft_cleanup +} + atf_test_case "reset_nonzero" "cleanup" reset_nonzero_head() { @@ -489,6 +522,7 @@ atf_init_test_cases() atf_add_test_case "v4_counters" atf_add_test_case "v6_counters" atf_add_test_case "zero_one" + atf_add_test_case "zero_twice" atf_add_test_case "reset_nonzero" atf_add_test_case "pr251414" atf_add_test_case "automatic"