Commit 5c1aba46 authored by Jozsef Kadlecsik's avatar Jozsef Kadlecsik Committed by Patrick McHardy

netfilter: ipset: fix checking the type revision at create command

The revision of the set type 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.
Signed-off-by: default avatarJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent 5e0c1eb7
...@@ -94,16 +94,28 @@ static int ...@@ -94,16 +94,28 @@ static int
find_set_type_get(const char *name, u8 family, u8 revision, find_set_type_get(const char *name, u8 family, u8 revision,
struct ip_set_type **found) struct ip_set_type **found)
{ {
struct ip_set_type *type;
int err;
rcu_read_lock(); rcu_read_lock();
*found = find_set_type(name, family, revision); *found = find_set_type(name, family, revision);
if (*found) { if (*found) {
int err = !try_module_get((*found)->me); err = !try_module_get((*found)->me) ? -EFAULT : 0;
rcu_read_unlock(); goto unlock;
return err ? -EFAULT : 0;
} }
/* 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(); rcu_read_unlock();
return try_to_load_type(name); return try_to_load_type(name);
unlock:
rcu_read_unlock();
return err;
} }
/* Find a given set type by name and family. /* 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) ...@@ -116,7 +128,7 @@ find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max)
struct ip_set_type *type; struct ip_set_type *type;
bool found = false; bool found = false;
*min = *max = 0; *min = 255; *max = 0;
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(type, &ip_set_type_list, list) list_for_each_entry_rcu(type, &ip_set_type_list, list)
if (STREQ(type->name, name) && if (STREQ(type->name, name) &&
...@@ -124,7 +136,7 @@ find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max) ...@@ -124,7 +136,7 @@ find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max)
found = true; found = true;
if (type->revision < *min) if (type->revision < *min)
*min = type->revision; *min = type->revision;
else if (type->revision > *max) if (type->revision > *max)
*max = type->revision; *max = type->revision;
} }
rcu_read_unlock(); rcu_read_unlock();
......
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