Skip to content

Commit 0af8c09

Browse files
Snorchummakynes
authored andcommitted
netfilter: x_tables: fix percpu counter block leak on error path when creating new netns
Here is the stack where we allocate percpu counter block: +-< __alloc_percpu +-< xt_percpu_counter_alloc +-< find_check_entry # {arp,ip,ip6}_tables.c +-< translate_table And it can be leaked on this code path: +-> ip6t_register_table +-> translate_table # allocates percpu counter block +-> xt_register_table # fails there is no freeing of the counter block on xt_register_table fail. Note: xt_percpu_counter_free should be called to free it like we do in do_replace through cleanup_entry helper (or in __ip6t_unregister_table). Probability of hitting this error path is low AFAICS (xt_register_table can only return ENOMEM here, as it is not replacing anything, as we are creating new netns, and it is hard to imagine that all previous allocations succeeded and after that one in xt_register_table failed). But it's worth fixing even the rare leak. Fixes: 71ae0df ("netfilter: xtables: use percpu rule counters") Signed-off-by: Pavel Tikhomirov <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent fdf6491 commit 0af8c09

File tree

3 files changed

+12
-0
lines changed

3 files changed

+12
-0
lines changed

net/ipv4/netfilter/arp_tables.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,6 +1525,10 @@ int arpt_register_table(struct net *net,
15251525

15261526
new_table = xt_register_table(net, table, &bootstrap, newinfo);
15271527
if (IS_ERR(new_table)) {
1528+
struct arpt_entry *iter;
1529+
1530+
xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1531+
cleanup_entry(iter, net);
15281532
xt_free_table_info(newinfo);
15291533
return PTR_ERR(new_table);
15301534
}

net/ipv4/netfilter/ip_tables.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,10 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
17411741

17421742
new_table = xt_register_table(net, table, &bootstrap, newinfo);
17431743
if (IS_ERR(new_table)) {
1744+
struct ipt_entry *iter;
1745+
1746+
xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1747+
cleanup_entry(iter, net);
17441748
xt_free_table_info(newinfo);
17451749
return PTR_ERR(new_table);
17461750
}

net/ipv6/netfilter/ip6_tables.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1750,6 +1750,10 @@ int ip6t_register_table(struct net *net, const struct xt_table *table,
17501750

17511751
new_table = xt_register_table(net, table, &bootstrap, newinfo);
17521752
if (IS_ERR(new_table)) {
1753+
struct ip6t_entry *iter;
1754+
1755+
xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1756+
cleanup_entry(iter, net);
17531757
xt_free_table_info(newinfo);
17541758
return PTR_ERR(new_table);
17551759
}

0 commit comments

Comments
 (0)