[ebtables] hold usage count on table module when it contains rules

Bart De Schuymer <[email protected]>
Newsgroups gmane.linux.network.bridge.ebtables.devel
Message-ID <[email protected]>
Hello Dave,

The patch below ensures an ebtables table which contains rules cannot be rmmod'ed.
This behaviour is conform with that of iptables.
The reason for this change is that users who see a table module with no reference
count could mistakenly think the table contains no rules.

cheers,
Bart

--- linux-2.5.65/net/bridge/netfilter/ebtable_filter.c	Mon Mar 17 22:44:43 2003
+++ linux-2.5.65-upd/net/bridge/netfilter/ebtable_filter.c	Sat Mar 22 09:50:20 2003
@@ -57,6 +57,7 @@ static struct ebt_table frame_filter =
 	.valid_hooks	= FILTER_VALID_HOOKS, 
 	.lock		= RW_LOCK_UNLOCKED,
 	.check		= check,
+	.me		= THIS_MODULE,
 };
 
 static unsigned int
--- linux-2.5.65/net/bridge/netfilter/ebtable_nat.c	Mon Mar 17 22:44:50 2003
+++ linux-2.5.65-upd/net/bridge/netfilter/ebtable_nat.c	Sat Mar 22 09:50:35 2003
@@ -56,6 +56,7 @@ static struct ebt_table frame_nat =
 	.valid_hooks	= NAT_VALID_HOOKS,
 	.lock		= RW_LOCK_UNLOCKED,
 	.check		= check,
+	.me		= THIS_MODULE,
 };
 
 static unsigned int
--- linux-2.5.65/net/bridge/netfilter/ebtable_broute.c	Mon Mar 17 22:43:37 2003
+++ linux-2.5.65-upd/net/bridge/netfilter/ebtable_broute.c	Sat Mar 22 09:49:28 2003
@@ -49,6 +49,7 @@ static struct ebt_table broute_table =
 	.valid_hooks	= 1 << NF_BR_BROUTING,
 	.lock		= RW_LOCK_UNLOCKED,
 	.check		= check,
+	.me		= THIS_MODULE,
 };
 
 static int ebt_broute(struct sk_buff **pskb)
--- linux-2.5.65/net/bridge/netfilter/ebtables.c	Mon Mar 17 22:44:02 2003
+++ linux-2.5.65-upd/net/bridge/netfilter/ebtables.c	Sat Mar 22 17:19:38 2003
@@ -969,8 +969,10 @@ static int do_replace(void *user, unsign
 		goto free_counterstmp;
 
 	t = find_table_lock(tmp.name, &ret, &ebt_mutex);
-	if (!t)
+	if (!t) {
+		ret = -ENOENT;
 		goto free_iterate;
+	}
 
 	/* the table doesn't like it */
 	if (t->check && (ret = t->check(newinfo, tmp.valid_hooks)))
@@ -984,6 +986,12 @@ static int do_replace(void *user, unsign
 
 	/* we have the mutex lock, so no danger in reading this pointer */
 	table = t->private;
+	/* make sure the table can only be rmmod'ed if it contains no rules */
+	if (!table->nentries && newinfo->nentries && !try_module_get(t->me)) {
+		ret = -ENOENT;
+		goto free_unlock;
+	} else if (table->nentries && !newinfo->nentries)
+		module_put(t->me);
 	/* we need an atomic snapshot of the counters */
 	write_lock_bh(&t->lock);
 	if (tmp.num_counters)
@@ -1168,6 +1176,11 @@ int ebt_register_table(struct ebt_table 
 		goto free_unlock;
 	}
 
+	/* Hold a reference count if the chains aren't empty */
+	if (newinfo->nentries && !try_module_get(table->me)) {
+		ret = -ENOENT;
+		goto free_unlock;
+	}
 	list_prepend(&ebt_tables, table);
 	up(&ebt_mutex);
 	return 0;
@@ -1196,8 +1209,6 @@ void ebt_unregister_table(struct ebt_tab
 	down(&ebt_mutex);
 	LIST_DELETE(&ebt_tables, table);
 	up(&ebt_mutex);
-	EBT_ENTRY_ITERATE(table->private->entries,
-	   table->private->entries_size, ebt_cleanup_entry, NULL);
 	if (table->private->entries)
 		vfree(table->private->entries);
 	if (table->private->chainstack) {
--- linux-2.5.65/include/linux/netfilter_bridge/ebtables.h	Mon Mar 17 22:44:45 2003
+++ linux-2.5.65-upd/include/linux/netfilter_bridge/ebtables.h	Sat Mar 22 09:49:06 2003
@@ -260,6 +260,7 @@ struct ebt_table
 	   unsigned int valid_hooks);
 	/* the data used by the kernel */
 	struct ebt_table_info *private;
+	struct module *me;
 };
 
 extern int ebt_register_table(struct ebt_table *table);



-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.