Commit c84ca954 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso

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: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 9d5c12a7
...@@ -301,6 +301,7 @@ int xt_data_to_user(void __user *dst, const void *src, ...@@ -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, void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
struct xt_counters_info *info, bool compat); 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, struct xt_table *xt_register_table(struct net *net,
const struct xt_table *table, const struct xt_table *table,
......
...@@ -883,7 +883,7 @@ static int __do_replace(struct net *net, const char *name, ...@@ -883,7 +883,7 @@ static int __do_replace(struct net *net, const char *name,
struct arpt_entry *iter; struct arpt_entry *iter;
ret = 0; ret = 0;
counters = vzalloc(num_counters * sizeof(struct xt_counters)); counters = xt_counters_alloc(num_counters);
if (!counters) { if (!counters) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
......
...@@ -1045,7 +1045,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks, ...@@ -1045,7 +1045,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
struct ipt_entry *iter; struct ipt_entry *iter;
ret = 0; ret = 0;
counters = vzalloc(num_counters * sizeof(struct xt_counters)); counters = xt_counters_alloc(num_counters);
if (!counters) { if (!counters) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
......
...@@ -1063,7 +1063,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks, ...@@ -1063,7 +1063,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
struct ip6t_entry *iter; struct ip6t_entry *iter;
ret = 0; ret = 0;
counters = vzalloc(num_counters * sizeof(struct xt_counters)); counters = xt_counters_alloc(num_counters);
if (!counters) { if (!counters) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
......
...@@ -1290,6 +1290,21 @@ static int xt_jumpstack_alloc(struct xt_table_info *i) ...@@ -1290,6 +1290,21 @@ static int xt_jumpstack_alloc(struct xt_table_info *i)
return 0; 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 * struct xt_table_info *
xt_replace_table(struct xt_table *table, xt_replace_table(struct xt_table *table,
unsigned int num_counters, unsigned int num_counters,
......
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