netfilter: x_tables: add counters allocation wrapper

allows to have size checks in a single spot.
This is supposed to reduce oom situations when fuzz-testing xtables.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Florian Westphal 2018-02-27 19:42:33 +01:00 committed by Pablo Neira Ayuso
parent 9d5c12a7c0
commit c84ca954ac
5 changed files with 19 additions and 3 deletions

View File

@ -301,6 +301,7 @@ int xt_data_to_user(void __user *dst, const void *src,
void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
struct xt_counters_info *info, bool compat);
struct xt_counters *xt_counters_alloc(unsigned int counters);
struct xt_table *xt_register_table(struct net *net,
const struct xt_table *table,

View File

@ -883,7 +883,7 @@ static int __do_replace(struct net *net, const char *name,
struct arpt_entry *iter;
ret = 0;
counters = vzalloc(num_counters * sizeof(struct xt_counters));
counters = xt_counters_alloc(num_counters);
if (!counters) {
ret = -ENOMEM;
goto out;

View File

@ -1045,7 +1045,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
struct ipt_entry *iter;
ret = 0;
counters = vzalloc(num_counters * sizeof(struct xt_counters));
counters = xt_counters_alloc(num_counters);
if (!counters) {
ret = -ENOMEM;
goto out;

View File

@ -1063,7 +1063,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
struct ip6t_entry *iter;
ret = 0;
counters = vzalloc(num_counters * sizeof(struct xt_counters));
counters = xt_counters_alloc(num_counters);
if (!counters) {
ret = -ENOMEM;
goto out;

View File

@ -1290,6 +1290,21 @@ static int xt_jumpstack_alloc(struct xt_table_info *i)
return 0;
}
struct xt_counters *xt_counters_alloc(unsigned int counters)
{
struct xt_counters *mem;
if (counters == 0 || counters > INT_MAX / sizeof(*mem))
return NULL;
counters *= sizeof(*mem);
if (counters > XT_MAX_TABLE_SIZE)
return NULL;
return vzalloc(counters);
}
EXPORT_SYMBOL(xt_counters_alloc);
struct xt_table_info *
xt_replace_table(struct xt_table *table,
unsigned int num_counters,