diff options
author | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2011-03-18 17:23:43 +0100 |
---|---|---|
committer | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2011-03-18 17:23:43 +0100 |
commit | 6b88433a9334f3f0fc44ee52867326ce20c4af15 (patch) | |
tree | 5eb70d2133d66d0645e747b036b6d47cc2a08acc | |
parent | 47af79effac38b048f924cf7fe3c739e8c250119 (diff) | |
download | ipset-6b88433a9334f3f0fc44ee52867326ce20c4af15.tar.gz |
Fix checking the revision of the set type at create command
The revision number was not checked at the create command: if the userspace
sent a valid set type but with not supported revision number, it'd create
a loop.
-rw-r--r-- | kernel/net/netfilter/ipset/ip_set_core.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/kernel/net/netfilter/ipset/ip_set_core.c b/kernel/net/netfilter/ipset/ip_set_core.c index b4c5600..295c803 100644 --- a/kernel/net/netfilter/ipset/ip_set_core.c +++ b/kernel/net/netfilter/ipset/ip_set_core.c @@ -94,16 +94,28 @@ static int find_set_type_get(const char *name, u8 family, u8 revision, struct ip_set_type **found) { + struct ip_set_type *type; + int err; + rcu_read_lock(); *found = find_set_type(name, family, revision); if (*found) { - int err = !try_module_get((*found)->me); - rcu_read_unlock(); - return err ? -EFAULT : 0; + err = !try_module_get((*found)->me) ? -EFAULT : 0; + goto unlock; } + /* Make sure the type is loaded but we don't support the revision */ + list_for_each_entry_rcu(type, &ip_set_type_list, list) + if (STREQ(type->name, name)) { + err = -IPSET_ERR_FIND_TYPE; + goto unlock; + } rcu_read_unlock(); return try_to_load_type(name); + +unlock: + rcu_read_unlock(); + return err; } /* Find a given set type by name and family. @@ -116,7 +128,7 @@ find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max) struct ip_set_type *type; bool found = false; - *min = *max = 0; + *min = 255; *max = 0; rcu_read_lock(); list_for_each_entry_rcu(type, &ip_set_type_list, list) if (STREQ(type->name, name) && |