[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