]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
netfilter: nf_tables: don't assume chain stats are set when jumplabel is set
authorFlorian Westphal <fw@strlen.de>
Sat, 5 May 2018 22:47:20 +0000 (00:47 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 8 Jul 2018 13:30:49 +0000 (15:30 +0200)
commit 009240940e84c1c089af88b454f7e804a4c5bd1b upstream.

nft_chain_stats_replace() and all other spots assume ->stats can be
NULL, but nft_update_chain_stats does not.  It must do this check,
just because the jump label is set doesn't mean all basechains have stats
assigned.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/netfilter/nf_tables_core.c

index dfd0bf3810d2e81690a4a2d3ac5648cb8d881090..942702a2776f6a57313b07c7f88bb67f98710016 100644 (file)
@@ -119,15 +119,22 @@ DEFINE_STATIC_KEY_FALSE(nft_counters_enabled);
 static noinline void nft_update_chain_stats(const struct nft_chain *chain,
                                            const struct nft_pktinfo *pkt)
 {
+       struct nft_base_chain *base_chain;
        struct nft_stats *stats;
 
-       local_bh_disable();
-       stats = this_cpu_ptr(rcu_dereference(nft_base_chain(chain)->stats));
-       u64_stats_update_begin(&stats->syncp);
-       stats->pkts++;
-       stats->bytes += pkt->skb->len;
-       u64_stats_update_end(&stats->syncp);
-       local_bh_enable();
+       base_chain = nft_base_chain(chain);
+       if (!base_chain->stats)
+               return;
+
+       stats = this_cpu_ptr(rcu_dereference(base_chain->stats));
+       if (stats) {
+               local_bh_disable();
+               u64_stats_update_begin(&stats->syncp);
+               stats->pkts++;
+               stats->bytes += pkt->skb->len;
+               u64_stats_update_end(&stats->syncp);
+               local_bh_enable();
+       }
 }
 
 struct nft_jumpstack {