Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 7 Oct 2014 10:54:53 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r272685 - projects/ipfw/sys/netpfil/ipfw
Message-ID:  <201410071054.s97AsrxU011209@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Tue Oct  7 10:54:53 2014
New Revision: 272685
URL: https://svnweb.freebsd.org/changeset/base/272685

Log:
  * Fix crash in interface tracker due to using old "linked" field.
  * Ensure we're flushing entries without any locks held.
  * Free memory in (rare) case when interface tracker fails to register ifp.
  * Add KASSERT on table values refcounts.

Modified:
  projects/ipfw/sys/netpfil/ipfw/ip_fw_iface.c
  projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h
  projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c
  projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c
  projects/ipfw/sys/netpfil/ipfw/ip_fw_table_value.c

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_iface.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_iface.c	Tue Oct  7 10:36:06 2014	(r272684)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_iface.c	Tue Oct  7 10:54:53 2014	(r272685)
@@ -392,8 +392,7 @@ ipfw_iface_del_notify(struct ip_fw_chain
 	IPFW_UH_WLOCK_ASSERT(ch);
 
 	iif = ic->iface;
-	if (ic->linked != 0)
-		TAILQ_REMOVE(&iif->consumers, ic, next);
+	TAILQ_REMOVE(&iif->consumers, ic, next);
 }
 
 /*

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h	Tue Oct  7 10:36:06 2014	(r272684)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_private.h	Tue Oct  7 10:54:53 2014	(r272685)
@@ -355,8 +355,6 @@ struct ipfw_ifc {
 	struct ipfw_iface	*iface;
 	ipfw_ifc_cb		*cb;
 	void			*cbdata;
-	int			linked;
-	int			spare;
 };
 
 /* Macro for working with various counters */

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c	Tue Oct  7 10:36:06 2014	(r272684)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c	Tue Oct  7 10:54:53 2014	(r272685)
@@ -564,10 +564,14 @@ add_table_entry(struct ip_fw_chain *ch, 
 	 */
 restart:
 	if (ts.modified != 0) {
+		IPFW_UH_WUNLOCK(ch);
 		flush_batch_buffer(ch, ta, tei, count, rollback,
 		    ta_buf_m, ta_buf);
 		memset(&ts, 0, sizeof(ts));
+		ta = NULL;
+		IPFW_UH_WLOCK(ch);
 	}
+
 	error = find_ref_table(ch, ti, tei, count, OP_ADD, &tc);
 	if (error != 0) {
 		IPFW_UH_WUNLOCK(ch);

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c	Tue Oct  7 10:36:06 2014	(r272684)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table_algo.c	Tue Oct  7 10:54:53 2014	(r272685)
@@ -2045,8 +2045,10 @@ ta_prepare_add_ifidx(struct ip_fw_chain 
 	ife->ic.cb = if_notifier;
 	ife->ic.cbdata = ife;
 
-	if (ipfw_iface_ref(ch, ifname, &ife->ic) != 0)
+	if (ipfw_iface_ref(ch, ifname, &ife->ic) != 0) {
+		free(ife, M_IPFW_TBL);
 		return (EINVAL);
+	}
 
 	/* Use ipfw_iface 'ifname' field as stable storage */
 	ife->no.name = ife->ic.iface->ifname;

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_table_value.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_table_value.c	Tue Oct  7 10:36:06 2014	(r272684)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_table_value.c	Tue Oct  7 10:54:53 2014	(r272685)
@@ -251,10 +251,9 @@ unref_table_value(struct namedobj_instan
 {
 	struct table_val_link *ptvl;
 
-	if (pval[kidx].refcnt > 1) {
-		pval[kidx].refcnt--;
+	KASSERT(pval[kidx].refcnt > 0, ("Refcount is 0 on kidx %d", kidx));
+	if (--pval[kidx].refcnt > 0)
 		return;
-	}
 
 	/* Last reference, delete item */
 	ptvl = (struct table_val_link *)ipfw_objhash_lookup_kidx(vi, kidx);
@@ -307,6 +306,8 @@ ipfw_unref_table_values(struct ip_fw_cha
 {
 	struct flush_args fa;
 
+	IPFW_UH_WLOCK_ASSERT(ch);
+
 	memset(&fa, 0, sizeof(fa));
 	fa.ch = ch;
 	fa.ta = ta;



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