Skip to content

Commit fd638a5

Browse files
committed
netfilter: nf_tables: fix GC transaction races with netns and netlink event exit path
jira VUlN-597 subsystem-sync netfilter:nf_tables 4.18.0-553 commit-author Pablo Neira Ayuso <pablo@netfilter.org> commit 6a33d8b upstream-diff Due to previous code syncronizations much of this code was already present. Branch 8_10 used as the source of truth. Netlink event path is missing a synchronization point with GC transactions. Add GC sequence number update to netns release path and netlink event path, any GC transaction losing race will be discarded. Fixes: 5f68718 ("netfilter: nf_tables: GC transaction API to avoid race with control plane") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Florian Westphal <fw@strlen.de> (cherry picked from commit 6a33d8b) Signed-off-by: Greg Rose <g.v.rose@ciq.com>
1 parent e6cb843 commit fd638a5

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8138,18 +8138,18 @@ static void nft_set_commit_update(struct list_head *set_update_list)
81388138

81398139
static unsigned int nft_gc_seq_begin(struct nftables_pernet *nft_net)
81408140
{
8141-
unsigned int gc_seq;
8141+
unsigned int gc_seq;
81428142

8143-
/* Bump gc counter, it becomes odd, this is the busy mark. */
8144-
gc_seq = READ_ONCE(nft_net->gc_seq);
8145-
WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
8143+
/* Bump gc counter, it becomes odd, this is the busy mark. */
8144+
gc_seq = READ_ONCE(nft_net->gc_seq);
8145+
WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
81468146

8147-
return gc_seq;
8147+
return gc_seq;
81488148
}
81498149

81508150
static void nft_gc_seq_end(struct nftables_pernet *nft_net, unsigned int gc_seq)
81518151
{
8152-
WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
8152+
WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
81538153
}
81548154

81558155
static int nf_tables_commit(struct net *net, struct sk_buff *skb)
@@ -8600,8 +8600,8 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb,
86008600
int ret;
86018601

86028602
gc_seq = nft_gc_seq_begin(nft_net);
8603-
ret = __nf_tables_abort(net, action);
8604-
nft_gc_seq_end(nft_net, gc_seq);
8603+
ret = __nf_tables_abort(net, action);
8604+
nft_gc_seq_end(nft_net, gc_seq);
86058605
mutex_unlock(&net->nft_commit_mutex);
86068606

86078607
return ret;
@@ -9254,17 +9254,17 @@ static void __net_exit nf_tables_exit_net(struct net *net)
92549254
gc_seq = nft_gc_seq_begin(nft_net);
92559255

92569256
if (!list_empty(&net->nft.commit_list) ||
9257-
!list_empty(&net->nft_module_list))
9258-
__nf_tables_abort(net, NFNL_ABORT_NONE);
9257+
!list_empty(&net->nft_module_list))
9258+
__nf_tables_abort(net, NFNL_ABORT_NONE);
92599259

92609260
__nft_release_tables(net);
92619261

92629262
nft_gc_seq_end(nft_net, gc_seq);
92639263

92649264
mutex_unlock(&net->nft_commit_mutex);
9265-
WARN_ON_ONCE(!list_empty(&net->nft.tables));
9266-
WARN_ON_ONCE(!list_empty(&net->nft_module_list));
9267-
WARN_ON_ONCE(!list_empty(&net->nft_notify_list));
9265+
WARN_ON_ONCE(!list_empty(&net->nft.tables));
9266+
WARN_ON_ONCE(!list_empty(&net->nft_module_list));
9267+
WARN_ON_ONCE(!list_empty(&net->nft_notify_list));
92689268
}
92699269

92709270
static void nf_tables_exit_batch(struct list_head *net_exit_list)

0 commit comments

Comments
 (0)