Skip to content

Commit c84ca95

Browse files
Florian Westphalummakynes
authored andcommitted
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>
1 parent 9d5c12a commit c84ca95

File tree

5 files changed

+19
-3
lines changed

5 files changed

+19
-3
lines changed

include/linux/netfilter/x_tables.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ int xt_data_to_user(void __user *dst, const void *src,
301301

302302
void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
303303
struct xt_counters_info *info, bool compat);
304+
struct xt_counters *xt_counters_alloc(unsigned int counters);
304305

305306
struct xt_table *xt_register_table(struct net *net,
306307
const struct xt_table *table,

net/ipv4/netfilter/arp_tables.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,7 @@ static int __do_replace(struct net *net, const char *name,
883883
struct arpt_entry *iter;
884884

885885
ret = 0;
886-
counters = vzalloc(num_counters * sizeof(struct xt_counters));
886+
counters = xt_counters_alloc(num_counters);
887887
if (!counters) {
888888
ret = -ENOMEM;
889889
goto out;

net/ipv4/netfilter/ip_tables.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1045,7 +1045,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
10451045
struct ipt_entry *iter;
10461046

10471047
ret = 0;
1048-
counters = vzalloc(num_counters * sizeof(struct xt_counters));
1048+
counters = xt_counters_alloc(num_counters);
10491049
if (!counters) {
10501050
ret = -ENOMEM;
10511051
goto out;

net/ipv6/netfilter/ip6_tables.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1063,7 +1063,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
10631063
struct ip6t_entry *iter;
10641064

10651065
ret = 0;
1066-
counters = vzalloc(num_counters * sizeof(struct xt_counters));
1066+
counters = xt_counters_alloc(num_counters);
10671067
if (!counters) {
10681068
ret = -ENOMEM;
10691069
goto out;

net/netfilter/x_tables.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,21 @@ static int xt_jumpstack_alloc(struct xt_table_info *i)
12901290
return 0;
12911291
}
12921292

1293+
struct xt_counters *xt_counters_alloc(unsigned int counters)
1294+
{
1295+
struct xt_counters *mem;
1296+
1297+
if (counters == 0 || counters > INT_MAX / sizeof(*mem))
1298+
return NULL;
1299+
1300+
counters *= sizeof(*mem);
1301+
if (counters > XT_MAX_TABLE_SIZE)
1302+
return NULL;
1303+
1304+
return vzalloc(counters);
1305+
}
1306+
EXPORT_SYMBOL(xt_counters_alloc);
1307+
12931308
struct xt_table_info *
12941309
xt_replace_table(struct xt_table *table,
12951310
unsigned int num_counters,

0 commit comments

Comments
 (0)