Commit 4228d368 authored by Bart De Schuymer's avatar Bart De Schuymer Committed by David S. Miller

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

parent f055e6c7
...@@ -260,6 +260,7 @@ struct ebt_table ...@@ -260,6 +260,7 @@ struct ebt_table
unsigned int valid_hooks); unsigned int valid_hooks);
/* the data used by the kernel */ /* the data used by the kernel */
struct ebt_table_info *private; struct ebt_table_info *private;
struct module *me;
}; };
extern int ebt_register_table(struct ebt_table *table); extern int ebt_register_table(struct ebt_table *table);
......
...@@ -49,6 +49,7 @@ static struct ebt_table broute_table = ...@@ -49,6 +49,7 @@ static struct ebt_table broute_table =
.valid_hooks = 1 << NF_BR_BROUTING, .valid_hooks = 1 << NF_BR_BROUTING,
.lock = RW_LOCK_UNLOCKED, .lock = RW_LOCK_UNLOCKED,
.check = check, .check = check,
.me = THIS_MODULE,
}; };
static int ebt_broute(struct sk_buff **pskb) static int ebt_broute(struct sk_buff **pskb)
......
...@@ -57,6 +57,7 @@ static struct ebt_table frame_filter = ...@@ -57,6 +57,7 @@ static struct ebt_table frame_filter =
.valid_hooks = FILTER_VALID_HOOKS, .valid_hooks = FILTER_VALID_HOOKS,
.lock = RW_LOCK_UNLOCKED, .lock = RW_LOCK_UNLOCKED,
.check = check, .check = check,
.me = THIS_MODULE,
}; };
static unsigned int static unsigned int
......
...@@ -56,6 +56,7 @@ static struct ebt_table frame_nat = ...@@ -56,6 +56,7 @@ static struct ebt_table frame_nat =
.valid_hooks = NAT_VALID_HOOKS, .valid_hooks = NAT_VALID_HOOKS,
.lock = RW_LOCK_UNLOCKED, .lock = RW_LOCK_UNLOCKED,
.check = check, .check = check,
.me = THIS_MODULE,
}; };
static unsigned int static unsigned int
......
...@@ -969,8 +969,10 @@ static int do_replace(void *user, unsigned int len) ...@@ -969,8 +969,10 @@ static int do_replace(void *user, unsigned int len)
goto free_counterstmp; goto free_counterstmp;
t = find_table_lock(tmp.name, &ret, &ebt_mutex); t = find_table_lock(tmp.name, &ret, &ebt_mutex);
if (!t) if (!t) {
ret = -ENOENT;
goto free_iterate; goto free_iterate;
}
/* the table doesn't like it */ /* the table doesn't like it */
if (t->check && (ret = t->check(newinfo, tmp.valid_hooks))) if (t->check && (ret = t->check(newinfo, tmp.valid_hooks)))
...@@ -984,6 +986,12 @@ static int do_replace(void *user, unsigned int len) ...@@ -984,6 +986,12 @@ static int do_replace(void *user, unsigned int len)
/* we have the mutex lock, so no danger in reading this pointer */ /* we have the mutex lock, so no danger in reading this pointer */
table = t->private; 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 */ /* we need an atomic snapshot of the counters */
write_lock_bh(&t->lock); write_lock_bh(&t->lock);
if (tmp.num_counters) if (tmp.num_counters)
...@@ -1168,6 +1176,11 @@ int ebt_register_table(struct ebt_table *table) ...@@ -1168,6 +1176,11 @@ int ebt_register_table(struct ebt_table *table)
goto free_unlock; 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); list_prepend(&ebt_tables, table);
up(&ebt_mutex); up(&ebt_mutex);
return 0; return 0;
...@@ -1196,8 +1209,6 @@ void ebt_unregister_table(struct ebt_table *table) ...@@ -1196,8 +1209,6 @@ void ebt_unregister_table(struct ebt_table *table)
down(&ebt_mutex); down(&ebt_mutex);
LIST_DELETE(&ebt_tables, table); LIST_DELETE(&ebt_tables, table);
up(&ebt_mutex); up(&ebt_mutex);
EBT_ENTRY_ITERATE(table->private->entries,
table->private->entries_size, ebt_cleanup_entry, NULL);
if (table->private->entries) if (table->private->entries)
vfree(table->private->entries); vfree(table->private->entries);
if (table->private->chainstack) { if (table->private->chainstack) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment