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: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Signed-off-by: Patrick McHardy <kaber@trash.net>hifive-unleashed-5.1
parent
5e0c1eb7e6
commit
5c1aba4678
|
@ -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)
|
||||||
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)
|
||||||
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();
|
||||||
|
|
Loading…
Reference in New Issue