⬢ DragonFlyBSD Kernel Audit
DF-3439 / fix.diff
← back to finding ↓ download raw
--- a/sys/net/ipfw3/ip_fw3.c
+++ b/sys/net/ipfw3/ip_fw3.c
@@ -825,11 +825,24 @@
 {
 	struct netmsg_del *dmsg = (struct netmsg_del *)nmsg;
 	struct ipfw3_context *ctx = fw3_ctx[mycpuid];
-	struct ip_fw *rule, *prev = NULL;
+	struct ip_fw *rule, *prev = NULL, *walk;
 
 	rule = ctx->rules;
 	while (rule!=NULL) {
 		if (rule->rulenum == dmsg->rulenum) {
+			/*
+			 * Rules that skip forward (skipto) cache the
+			 * pointer to their target rule in ->next_rule
+			 * (lookup_next_rule via check_skipto).
+			 * Invalidate every cached pointer targeting the
+			 * rule we are about to free so packet matching
+			 * can never follow a dangling next_rule into
+			 * freed memory (DF-3439).
+			 */
+			for (walk = ctx->rules; walk; walk = walk->next) {
+				if (walk->next_rule == rule)
+					walk->next_rule = NULL;
+			}
 			ip_fw3_delete_rule(ctx, prev, rule);
 			break;
 		}