mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
netfilter: nft_counter: Disable BH in nft_counter_offload_stats().
[ Upstream commit 1eacdd71b3436b54d5fc8218c4bb0187d92a6892 ]
The sequence counter nft_counter_seq is a per-CPU counter. There is no
lock associated with it. nft_counter_do_eval() is using the same counter
and disables BH which suggest that it can be invoked from a softirq.
This in turn means that nft_counter_offload_stats(), which disables only
preemption, can be interrupted by nft_counter_do_eval() leading to two
writer for one seqcount_t.
This can lead to loosing stats or reading statistics while they are
updated.
Disable BH during stats update in nft_counter_offload_stats() to ensure
one writer at a time.
Fixes: b72920f6e4 ("netfilter: nftables: counter hardware offload support")
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
72da240aaf
commit
75eb4a8c11
@@ -264,7 +264,7 @@ static void nft_counter_offload_stats(struct nft_expr *expr,
|
||||
struct nft_counter *this_cpu;
|
||||
seqcount_t *myseq;
|
||||
|
||||
preempt_disable();
|
||||
local_bh_disable();
|
||||
this_cpu = this_cpu_ptr(priv->counter);
|
||||
myseq = this_cpu_ptr(&nft_counter_seq);
|
||||
|
||||
@@ -272,7 +272,7 @@ static void nft_counter_offload_stats(struct nft_expr *expr,
|
||||
this_cpu->packets += stats->pkts;
|
||||
this_cpu->bytes += stats->bytes;
|
||||
write_seqcount_end(myseq);
|
||||
preempt_enable();
|
||||
local_bh_enable();
|
||||
}
|
||||
|
||||
void nft_counter_init_seqcount(void)
|
||||
|
||||
Reference in New Issue
Block a user