DragonFlyBSD Kernel Audit
DF-0632 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/net/ipfw3_basic/ip_fw3_state.c b/sys/net/ipfw3_basic/ip_fw3_state.c
--- a/sys/net/ipfw3_basic/ip_fw3_state.c
+++ b/sys/net/ipfw3_basic/ip_fw3_state.c
@@ -399,6 +399,13 @@
 			kfree(s, M_IPFW3_STATE);
 		}
 	}
+	/* DF-0632: reset counters when flushing all states. */
+	state_ctx->count_tcp_in = 0;
+	state_ctx->count_tcp_out = 0;
+	state_ctx->count_udp_in = 0;
+	state_ctx->count_udp_out = 0;
+	state_ctx->count_icmp_in = 0;
+	state_ctx->count_icmp_out = 0;
 	netisr_forwardmsg_all(&nmsg->base, mycpuid + 1);
 }
 
@@ -546,36 +553,48 @@
 		if (time_uptime - s->timestamp > sysctl_var_icmp_timeout) {
 			RB_REMOVE(fw3_state_tree, &state_ctx->rb_icmp_in, s);
 			kfree(s, M_IPFW3_STATE);
+		if (state_ctx->count_icmp_in > 0)
+			state_ctx->count_icmp_in--;
 		}
 	}
 	RB_FOREACH_SAFE(s, fw3_state_tree, &state_ctx->rb_icmp_out, tmp) {
 		if (time_uptime - s->timestamp > sysctl_var_icmp_timeout) {
 			RB_REMOVE(fw3_state_tree, &state_ctx->rb_icmp_out, s);
 			kfree(s, M_IPFW3_STATE);
+		if (state_ctx->count_icmp_out > 0)
+			state_ctx->count_icmp_out--;
 		}
 	}
 	RB_FOREACH_SAFE(s, fw3_state_tree, &state_ctx->rb_tcp_in, tmp) {
 		if (time_uptime - s->timestamp > sysctl_var_tcp_timeout) {
 			RB_REMOVE(fw3_state_tree, &state_ctx->rb_tcp_in, s);
 			kfree(s, M_IPFW3_STATE);
+		if (state_ctx->count_tcp_in > 0)
+			state_ctx->count_tcp_in--;
 		}
 	}
 	RB_FOREACH_SAFE(s, fw3_state_tree, &state_ctx->rb_tcp_out, tmp) {
 		if (time_uptime - s->timestamp > sysctl_var_tcp_timeout) {
 			RB_REMOVE(fw3_state_tree, &state_ctx->rb_tcp_out, s);
 			kfree(s, M_IPFW3_STATE);
+		if (state_ctx->count_tcp_out > 0)
+			state_ctx->count_tcp_out--;
 		}
 	}
 	RB_FOREACH_SAFE(s, fw3_state_tree, &state_ctx->rb_udp_in, tmp) {
 		if (time_uptime - s->timestamp > sysctl_var_udp_timeout) {
 			RB_REMOVE(fw3_state_tree, &state_ctx->rb_udp_in, s);
 			kfree(s, M_IPFW3_STATE);
+		if (state_ctx->count_udp_in > 0)
+			state_ctx->count_udp_in--;
 		}
 	}
 	RB_FOREACH_SAFE(s, fw3_state_tree, &state_ctx->rb_udp_out, tmp) {
 		if (time_uptime - s->timestamp > sysctl_var_udp_timeout) {
 			RB_REMOVE(fw3_state_tree, &state_ctx->rb_udp_out, s);
 			kfree(s, M_IPFW3_STATE);
+		if (state_ctx->count_udp_out > 0)
+			state_ctx->count_udp_out--;
 		}
 	}
 	netisr_forwardmsg_all(&nmsg->base, mycpuid + 1);