diff options
author | Bart De Schuymer <bdschuym@pandora.be> | 2003-05-03 18:13:34 +0000 |
---|---|---|
committer | Bart De Schuymer <bdschuym@pandora.be> | 2003-05-03 18:13:34 +0000 |
commit | 8f3864732f38c72c018138269b3e2109c3b3cd40 (patch) | |
tree | 4158e922d1934f2a4b8287c54009a02daa5be30a /kernel/linux2.5/net/bridge/netfilter/ebtables.c | |
parent | a3d12c061c5143c29de790a342a36e434aa3e728 (diff) |
update to 2.5.68+pkttype
Diffstat (limited to 'kernel/linux2.5/net/bridge/netfilter/ebtables.c')
-rw-r--r-- | kernel/linux2.5/net/bridge/netfilter/ebtables.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/kernel/linux2.5/net/bridge/netfilter/ebtables.c b/kernel/linux2.5/net/bridge/netfilter/ebtables.c index e297900..8729898 100644 --- a/kernel/linux2.5/net/bridge/netfilter/ebtables.c +++ b/kernel/linux2.5/net/bridge/netfilter/ebtables.c @@ -175,6 +175,10 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb, char *base; struct ebt_table_info *private = table->private; + /* FIXME: Push down to extensions --RR */ + if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0) + return NF_DROP; + read_lock_bh(&table->lock); cb_base = COUNTER_BASE(private->counters, private->nentries, smp_processor_id()); @@ -969,8 +973,10 @@ static int do_replace(void *user, unsigned int len) 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 +990,12 @@ static int do_replace(void *user, unsigned int len) /* 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 +1180,11 @@ int ebt_register_table(struct ebt_table *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 +1213,6 @@ void ebt_unregister_table(struct ebt_table *table) 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) { |