@@ -151,6 +151,7 @@ static struct nft_trans *nft_trans_alloc_gfp(const struct nft_ctx *ctx,
151
151
return NULL ;
152
152
153
153
INIT_LIST_HEAD (& trans -> list );
154
+ INIT_LIST_HEAD (& trans -> binding_list );
154
155
trans -> msg_type = msg_type ;
155
156
trans -> ctx = * ctx ;
156
157
@@ -163,9 +164,15 @@ static struct nft_trans *nft_trans_alloc(const struct nft_ctx *ctx,
163
164
return nft_trans_alloc_gfp (ctx , msg_type , size , GFP_KERNEL );
164
165
}
165
166
166
- static void nft_trans_destroy (struct nft_trans * trans )
167
+ static void nft_trans_list_del (struct nft_trans * trans )
167
168
{
168
169
list_del (& trans -> list );
170
+ list_del (& trans -> binding_list );
171
+ }
172
+
173
+ static void nft_trans_destroy (struct nft_trans * trans )
174
+ {
175
+ nft_trans_list_del (trans );
169
176
kfree (trans );
170
177
}
171
178
@@ -357,6 +364,14 @@ static void nft_trans_commit_list_add_tail(struct net *net, struct nft_trans *tr
357
364
{
358
365
struct nftables_pernet * nft_net = nft_pernet (net );
359
366
367
+ switch (trans -> msg_type ) {
368
+ case NFT_MSG_NEWSET :
369
+ if (!nft_trans_set_update (trans ) &&
370
+ nft_set_is_anonymous (nft_trans_set (trans )))
371
+ list_add_tail (& trans -> binding_list , & nft_net -> binding_list );
372
+ break ;
373
+ }
374
+
360
375
list_add_tail (& trans -> list , & nft_net -> commit_list );
361
376
}
362
377
@@ -9111,7 +9126,7 @@ static void nf_tables_trans_destroy_work(struct work_struct *w)
9111
9126
synchronize_rcu ();
9112
9127
9113
9128
list_for_each_entry_safe (trans , next , & head , list ) {
9114
- list_del ( & trans -> list );
9129
+ nft_trans_list_del ( trans );
9115
9130
nft_commit_release (trans );
9116
9131
}
9117
9132
}
@@ -9476,6 +9491,19 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
9476
9491
return 0 ;
9477
9492
}
9478
9493
9494
+ list_for_each_entry (trans , & nft_net -> binding_list , binding_list ) {
9495
+ switch (trans -> msg_type ) {
9496
+ case NFT_MSG_NEWSET :
9497
+ if (!nft_trans_set_update (trans ) &&
9498
+ nft_set_is_anonymous (nft_trans_set (trans )) &&
9499
+ !nft_trans_set_bound (trans )) {
9500
+ pr_warn_once ("nftables ruleset with unbound set\n" );
9501
+ return - EINVAL ;
9502
+ }
9503
+ break ;
9504
+ }
9505
+ }
9506
+
9479
9507
/* 0. Validate ruleset, otherwise roll back for error reporting. */
9480
9508
if (nf_tables_validate (net ) < 0 )
9481
9509
return - EAGAIN ;
@@ -9989,7 +10017,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
9989
10017
9990
10018
list_for_each_entry_safe_reverse (trans , next ,
9991
10019
& nft_net -> commit_list , list ) {
9992
- list_del ( & trans -> list );
10020
+ nft_trans_list_del ( trans );
9993
10021
nf_tables_abort_release (trans );
9994
10022
}
9995
10023
@@ -10765,6 +10793,7 @@ static int __net_init nf_tables_init_net(struct net *net)
10765
10793
10766
10794
INIT_LIST_HEAD (& nft_net -> tables );
10767
10795
INIT_LIST_HEAD (& nft_net -> commit_list );
10796
+ INIT_LIST_HEAD (& nft_net -> binding_list );
10768
10797
INIT_LIST_HEAD (& nft_net -> module_list );
10769
10798
INIT_LIST_HEAD (& nft_net -> notify_list );
10770
10799
mutex_init (& nft_net -> commit_mutex );
0 commit comments