diff options
author | Florian Westphal <fw@strlen.de> | 2018-05-05 18:47:20 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2018-05-08 08:15:33 -0400 |
commit | 009240940e84c1c089af88b454f7e804a4c5bd1b (patch) | |
tree | 3fdc62f78daf56610d35ee6139b6433b93a8aa9b | |
parent | a44f6d82a471aa52fe218e43105fbe3c458fc5a6 (diff) |
netfilter: nf_tables: don't assume chain stats are set when jumplabel is set
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>
-rw-r--r-- | net/netfilter/nf_tables_core.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index dfd0bf3810d2..942702a2776f 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c | |||
@@ -119,15 +119,22 @@ DEFINE_STATIC_KEY_FALSE(nft_counters_enabled); | |||
119 | static noinline void nft_update_chain_stats(const struct nft_chain *chain, | 119 | static noinline void nft_update_chain_stats(const struct nft_chain *chain, |
120 | const struct nft_pktinfo *pkt) | 120 | const struct nft_pktinfo *pkt) |
121 | { | 121 | { |
122 | struct nft_base_chain *base_chain; | ||
122 | struct nft_stats *stats; | 123 | struct nft_stats *stats; |
123 | 124 | ||
124 | local_bh_disable(); | 125 | base_chain = nft_base_chain(chain); |
125 | stats = this_cpu_ptr(rcu_dereference(nft_base_chain(chain)->stats)); | 126 | if (!base_chain->stats) |
126 | u64_stats_update_begin(&stats->syncp); | 127 | return; |
127 | stats->pkts++; | 128 | |
128 | stats->bytes += pkt->skb->len; | 129 | stats = this_cpu_ptr(rcu_dereference(base_chain->stats)); |
129 | u64_stats_update_end(&stats->syncp); | 130 | if (stats) { |
130 | local_bh_enable(); | 131 | local_bh_disable(); |
132 | u64_stats_update_begin(&stats->syncp); | ||
133 | stats->pkts++; | ||
134 | stats->bytes += pkt->skb->len; | ||
135 | u64_stats_update_end(&stats->syncp); | ||
136 | local_bh_enable(); | ||
137 | } | ||
131 | } | 138 | } |
132 | 139 | ||
133 | struct nft_jumpstack { | 140 | struct nft_jumpstack { |