From nobody Wed Oct 28 20:35:37 2026 X-Original-To: dev-commits-src-branches@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 4jFJyx3y97z6x5js for ; Wed, 28 Oct 2026 20:35:37 +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 4jFJyx3N7nz4QgR for ; Wed, 28 Oct 2026 20:35:37 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793219737; 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=fPAhHRJs+rkK+WU+pSN+CcrnfdgYxWg58u9XXvy95fs=; b=LPIv4UWaGzr5KxF3SuMByUZ8/aCxHMWid9qBRq1skrSw2y74gUSb8Dd/saaz9HYTvbqEbH xSI1VAq+Y8LqFr96YyphqX/xxGcrBjnkCaLmolAWdyFnI96WcLfzz5qRhy0F/OagCgYYd+ xpyOdgaHh23KMrXUGZk7+WzOjMMn5FFp/H4ga6qbHIzkWjvbqpJh9yHrymNogZOJ9uCmUb iOGGtYtjcFUcLK7vlq9zC2PVXBH73kh/NomuxTg3wdwvnESc8f6akBRZxBejCyTFQ+qSRw 1lubS5sIJxDfjUi+ft7ZEFzV+WQhYrDfm4Nf/7YBo2mCvy6KyRjXJLn5YgGLKg== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1793219737; b=YDfurq7ZH8eUuMVGx/jp7NHKruo9O1Rfh15BLK8nFeQcYH4sfOw59iyWagXoZWWDra1Z2/ gm4n6SOyo2ukABm0wwPwUlQR4d1njQo2Ue6fEej9XExBWPsYXmkckgzMBgDblb2eJApfWq c+ia2e5y28by2efcrxFTCCeJ2NnX/U7RX2c0QC4Q1wU+5MPyxzU9YVygiaamgm8xRna8Gu GvnWRzaDflSzIYN7eGDs9QNupVH4af3Bi32fuF/qV8/Y2fCfmCM96m2Q2mNsragk1nyG+q UvPqhfqTAIzoY7CUK5LYIgMPCm0CgXL7HdpnrQUwbyYI+qgqoxKBQOWcWZeRLA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793219737; 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=fPAhHRJs+rkK+WU+pSN+CcrnfdgYxWg58u9XXvy95fs=; b=TY3FBYwiOEXk9kgZMGT1avyJI3/6CuJWdDGI3QmNpZn9b4Y3/4bgNFhKtSZemsyknsBQlR yWhd0GTHuqAozRNwmTnDvaS/fTa6BmLwGlH7iB4HePRtmUp+uQBImnO0mf+OHgiNlZh8CH O/19kFPW4dcO0TYMBHvNrLLXJJOKcXS2eng20MS4JnYASDiwyaHgBLXwO8slHALftjYghh RouL8sj8LWByQwKPM20+CCF8XEB18ZWQp6jzfRuOaJTReHl/msOOgj8IZYukUw+1StkN3A UgSXpsbPp+flvBG8dOO3r/78wW5X/A6hrs+v2C11KSsFqH2L/1h3XBtEHEM+IA== 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 4jFJyx32XYz1Mjx for ; Wed, 28 Oct 2026 20:35:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1d0ac by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 28 Oct 2026 20:35:37 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: R. Christian McDonald Subject: git: 1db6e7e987e5 - stable/15 - 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-branches X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: Commits to the stable branches of the FreeBSD 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/15 X-Git-Reftype: branch X-Git-Commit: 1db6e7e987e5cb6f778becb8f057e79ab40dabe0 Auto-Submitted: auto-generated Date: Wed, 28 Oct 2026 20:35:37 +0000 Message-Id: <6ae25c99.1d0ac.20222055@gitrepo.freebsd.org> The branch stable/15 has been updated by rcm: URL: https://cgit.FreeBSD.org/src/commit/?id=1db6e7e987e5cb6f778becb8f057e79ab40dabe0 commit 1db6e7e987e5cb6f778becb8f057e79ab40dabe0 Author: R. Christian McDonald AuthorDate: 2026-09-29 00:07:22 +0000 Commit: R. Christian McDonald CommitDate: 2026-10-28 20:34:01 +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 73ec18fa7646..1785e8a78d31 100644 --- a/sys/netpfil/pf/pf_table.c +++ b/sys/netpfil/pf/pf_table.c @@ -647,16 +647,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 6f7c0939d31a..213d63af8927 100644 --- a/tests/sys/netpfil/pf/table.sh +++ b/tests/sys/netpfil/pf/table.sh @@ -290,6 +290,39 @@ zero_all_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() { @@ -714,6 +747,7 @@ atf_init_test_cases() atf_add_test_case "match_counters" atf_add_test_case "zero_one" atf_add_test_case "zero_all" + atf_add_test_case "zero_twice" atf_add_test_case "reset_nonzero" atf_add_test_case "pr251414" atf_add_test_case "automatic"