Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 Dec 2025 09:02:54 -0800
From:      Gleb Smirnoff <glebius@freebsd.org>
To:        "Dan Mahoney (ports)" <freebsd@gushi.org>, Alastair Hogge <agh@riseup.net>
Cc:        FreeBSD User <freebsd@walstatt-de.de>, Ronald Klop <ronald-lists@klop.ws>, FreeBSD CURRENT <freebsd-current@freebsd.org>
Subject:   Re: CURRENT: kernel panic in IPFW while stopping jails
Message-ID:  <aVQFvirQiq9_2ZgB@cell.glebi.us>
In-Reply-To: <291e26bfbe2b51835f7672db3a2e3593@riseup.net> <0F907415-3277-4EA9-9D8E-C8D0905EC6AA@gushi.org>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]
  Hi,

I have found the problem, thanks to Alastair for a core file.

The problem affects rules with automatic rule numbers and logging.

The attached patch should fix the problem, but it is not a final version.

Dan & Alastair, if any of you can confirm that the patch heals your setup - I
will appreciate.

Again very sorry for this breakage.

-- 
Gleb Smirnoff

[-- Attachment #2 --]
diff --git a/sys/netpfil/ipfw/ip_fw_bpf.c b/sys/netpfil/ipfw/ip_fw_bpf.c
index d9897f700d57..2a9f8d889f43 100644
--- a/sys/netpfil/ipfw/ip_fw_bpf.c
+++ b/sys/netpfil/ipfw/ip_fw_bpf.c
@@ -81,6 +81,8 @@ ipfw_tap_alloc(uint32_t rule)
 	struct ipfw_tap	*tap, key = { .rule = rule };
 	int n __diagused;
 
+	MPASS(rule > 0);
+
 	tap = RB_FIND(tap_tree, &V_tap_tree, &key);
 	if (tap != NULL) {
 		MPASS(tap->rule == rule);
@@ -106,9 +108,10 @@ ipfw_tap_alloc(uint32_t rule)
 void
 ipfw_tap_free(uint32_t rule)
 {
-
 	struct ipfw_tap	*tap, key = { .rule = rule };
 
+	MPASS(rule > 0);
+
 	tap = RB_FIND(tap_tree, &V_tap_tree, &key);
 	MPASS(tap != NULL);
 	if (--tap->refs == 0) {
diff --git a/sys/netpfil/ipfw/ip_fw_sockopt.c b/sys/netpfil/ipfw/ip_fw_sockopt.c
index a91fb2e84da9..38e134a21141 100644
--- a/sys/netpfil/ipfw/ip_fw_sockopt.c
+++ b/sys/netpfil/ipfw/ip_fw_sockopt.c
@@ -210,7 +210,7 @@ ipfw_free_rule(struct ip_fw *rule)
 	 */
 	if (rule->refcnt > 1)
 		return;
-	if (ACTION_PTR(rule)->opcode == O_LOG)
+	if (ACTION_PTR(rule)->opcode == O_LOG && rule->rulenum != 0)
 		ipfw_tap_free(rule->rulenum);
 	uma_zfree_pcpu(V_ipfw_cntr_zone, rule->cntr);
 	free(rule, M_IPFW);
@@ -552,6 +552,8 @@ ipfw_commit_rules(struct ip_fw_chain *chain, struct rule_check_info *rci,
 			memcpy((char *)ci->urule + ci->urule_numoff, &rulenum,
 			    sizeof(rulenum));
 		}
+		if (ACTION_PTR(krule)->opcode == O_LOG)
+			ipfw_tap_alloc(krule->rulenum);
 	}
 
 	/* duplicate the remaining part, we always have the default rule */
@@ -2513,9 +2515,6 @@ import_rule_v1(struct ip_fw_chain *chain, struct rule_check_info *ci)
 
 	/* Copy opcodes */
 	memcpy(krule->cmd, urule->cmd, krule->cmd_len * sizeof(uint32_t));
-
-	if (ACTION_PTR(krule)->opcode == O_LOG)
-		ipfw_tap_alloc(krule->rulenum);
 }
 
 /*
help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?aVQFvirQiq9_2ZgB>