Skip to content

Commit 4942471

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-511 commit-author Pablo Neira Ayuso <[email protected]> commit 6a33d8b upstream-diff Due to previous code syncronizations much of this code was already present. However, as the folks at netfilter are wont to do, they mixed in space removing formatting changes with a patch that had nothing to do with fixing formatting. :( 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 <[email protected]> Signed-off-by: Florian Westphal <[email protected]> (cherry picked from commit 6a33d8b) Signed-off-by: Greg Rose <[email protected]>
1 parent 35d3b70 commit 4942471

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
@@ -8139,18 +8139,18 @@ static void nft_set_commit_update(struct list_head *set_update_list)
81398139

81408140
static unsigned int nft_gc_seq_begin(struct nftables_pernet *nft_net)
81418141
{
8142-
unsigned int gc_seq;
8142+
unsigned int gc_seq;
81438143

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

8148-
return gc_seq;
8148+
return gc_seq;
81498149
}
81508150

81518151
static void nft_gc_seq_end(struct nftables_pernet *nft_net, unsigned int gc_seq)
81528152
{
8153-
WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
8153+
WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
81548154
}
81558155

81568156
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)