This is a note to let you know that I've just added the patch titled
netfilter: x_tables: pass xt_counters struct instead of packet counter
to the 4.9-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git%3Ba=su...
The filename of the patch is: netfilter-x_tables-pass-xt_counters-struct-instead-of-packet-counter.patch and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let stable@vger.kernel.org know about it.
From 4d31eef5176df06f218201bc9c0ce40babb41660 Mon Sep 17 00:00:00 2001
From: Florian Westphal fw@strlen.de Date: Tue, 22 Nov 2016 14:44:17 +0100 Subject: netfilter: x_tables: pass xt_counters struct instead of packet counter
From: Florian Westphal fw@strlen.de
commit 4d31eef5176df06f218201bc9c0ce40babb41660 upstream.
On SMP we overload the packet counter (unsigned long) to contain percpu offset. Hide this from callers and pass xt_counters address instead.
Preparation patch to allocate the percpu counters in page-sized batch chunks.
Signed-off-by: Florian Westphal fw@strlen.de Acked-by: Eric Dumazet edumazet@google.com Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/netfilter/x_tables.h | 6 +----- net/ipv4/netfilter/arp_tables.c | 4 ++-- net/ipv4/netfilter/ip_tables.c | 4 ++-- net/ipv6/netfilter/ip6_tables.c | 5 ++--- net/netfilter/x_tables.c | 9 +++++++++ 5 files changed, 16 insertions(+), 12 deletions(-)
--- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -402,11 +402,7 @@ static inline unsigned long xt_percpu_co
return 0; } -static inline void xt_percpu_counter_free(u64 pcnt) -{ - if (nr_cpu_ids > 1) - free_percpu((void __percpu *) (unsigned long) pcnt); -} +void xt_percpu_counter_free(struct xt_counters *cnt);
static inline struct xt_counters * xt_get_this_cpu_counter(struct xt_counters *cnt) --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -447,7 +447,7 @@ find_check_entry(struct arpt_entry *e, c err: module_put(t->u.kernel.target->me); out: - xt_percpu_counter_free(e->counters.pcnt); + xt_percpu_counter_free(&e->counters);
return ret; } @@ -527,7 +527,7 @@ static inline void cleanup_entry(struct if (par.target->destroy != NULL) par.target->destroy(&par); module_put(par.target->me); - xt_percpu_counter_free(e->counters.pcnt); + xt_percpu_counter_free(&e->counters); }
/* Checks and translates the user-supplied table segment (held in --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -591,7 +591,7 @@ find_check_entry(struct ipt_entry *e, st cleanup_match(ematch, net); }
- xt_percpu_counter_free(e->counters.pcnt); + xt_percpu_counter_free(&e->counters);
return ret; } @@ -679,7 +679,7 @@ cleanup_entry(struct ipt_entry *e, struc if (par.target->destroy != NULL) par.target->destroy(&par); module_put(par.target->me); - xt_percpu_counter_free(e->counters.pcnt); + xt_percpu_counter_free(&e->counters); }
/* Checks and translates the user-supplied table segment (held in --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -620,7 +620,7 @@ find_check_entry(struct ip6t_entry *e, s cleanup_match(ematch, net); }
- xt_percpu_counter_free(e->counters.pcnt); + xt_percpu_counter_free(&e->counters);
return ret; } @@ -707,8 +707,7 @@ static void cleanup_entry(struct ip6t_en if (par.target->destroy != NULL) par.target->destroy(&par); module_put(par.target->me); - - xt_percpu_counter_free(e->counters.pcnt); + xt_percpu_counter_free(&e->counters); }
/* Checks and translates the user-supplied table segment (held in --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -1619,6 +1619,15 @@ void xt_proto_fini(struct net *net, u_in } EXPORT_SYMBOL_GPL(xt_proto_fini);
+void xt_percpu_counter_free(struct xt_counters *counters) +{ + unsigned long pcnt = counters->pcnt; + + if (nr_cpu_ids > 1) + free_percpu((void __percpu *)pcnt); +} +EXPORT_SYMBOL_GPL(xt_percpu_counter_free); + static int __net_init xt_net_init(struct net *net) { int i;
Patches currently in stable-queue which might be from fw@strlen.de are
queue-4.9/netfilter-add-back-stackpointer-size-checks.patch queue-4.9/netfilter-x_tables-pack-percpu-counter-allocations.patch queue-4.9/netfilter-ipv6-fix-use-after-free-write-in-nf_nat_ipv6_manip_pkt.patch queue-4.9/netfilter-x_tables-pass-xt_counters-struct-instead-of-packet-counter.patch queue-4.9/netfilter-ebtables-config_compat-don-t-trust-userland-offsets.patch queue-4.9/netfilter-bridge-ebt_among-add-missing-match-size-checks.patch queue-4.9/netfilter-x_tables-pass-xt_counters-struct-to-counter-allocator.patch