Skip to content

Commit c080b6c

Browse files
angrqNipaLocal
authored andcommitted
netfilter: nft_counter: Fix reset of counters on 32bit archs
nft_counter_reset() calls u64_stats_add() with a negative value to reset the counter. This will work on 64bit archs, hence the negative value added will wrap as a 64bit value which then can wrap the stat counter as well. On 32bit archs, the added negative value will wrap as a 32bit value and _not_ wrapping the stat counter properly. In most cases, this would just lead to a very large 32bit value being added to the stat counter. Fix by introducing u64_stats_sub(). Fixes: 4a1d3ac ("netfilter: nft_counter: Use u64_stats_t for statistic.") Signed-off-by: Anders Grahn <anders.grahn@westermo.com> Signed-off-by: NipaLocal <nipa@local>
1 parent a54e195 commit c080b6c

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

include/linux/u64_stats_sync.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ static inline void u64_stats_add(u64_stats_t *p, unsigned long val)
8989
local64_add(val, &p->v);
9090
}
9191

92+
static inline void u64_stats_sub(u64_stats_t *p, s64 val)
93+
{
94+
local64_sub(val, &p->v);
95+
}
96+
9297
static inline void u64_stats_inc(u64_stats_t *p)
9398
{
9499
local64_inc(&p->v);
@@ -130,6 +135,11 @@ static inline void u64_stats_add(u64_stats_t *p, unsigned long val)
130135
p->v += val;
131136
}
132137

138+
static inline void u64_stats_sub(u64_stats_t *p, s64 val)
139+
{
140+
p->v -= val;
141+
}
142+
133143
static inline void u64_stats_inc(u64_stats_t *p)
134144
{
135145
p->v++;

net/netfilter/nft_counter.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ static void nft_counter_reset(struct nft_counter_percpu_priv *priv,
117117
nft_sync = this_cpu_ptr(&nft_counter_sync);
118118

119119
u64_stats_update_begin(nft_sync);
120-
u64_stats_add(&this_cpu->packets, -total->packets);
121-
u64_stats_add(&this_cpu->bytes, -total->bytes);
120+
u64_stats_sub(&this_cpu->packets, total->packets);
121+
u64_stats_sub(&this_cpu->bytes, total->bytes);
122122
u64_stats_update_end(nft_sync);
123123

124124
local_bh_enable();

0 commit comments

Comments
 (0)