@@ -151,6 +151,7 @@ static struct nft_trans *nft_trans_alloc_gfp(const struct nft_ctx *ctx,
151151 return NULL ;
152152
153153 INIT_LIST_HEAD (& trans -> list );
154+ INIT_LIST_HEAD (& trans -> binding_list );
154155 trans -> msg_type = msg_type ;
155156 trans -> ctx = * ctx ;
156157
@@ -163,9 +164,15 @@ static struct nft_trans *nft_trans_alloc(const struct nft_ctx *ctx,
163164 return nft_trans_alloc_gfp (ctx , msg_type , size , GFP_KERNEL );
164165}
165166
166- static void nft_trans_destroy (struct nft_trans * trans )
167+ static void nft_trans_list_del (struct nft_trans * trans )
167168{
168169 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 );
169176 kfree (trans );
170177}
171178
@@ -357,6 +364,14 @@ static void nft_trans_commit_list_add_tail(struct net *net, struct nft_trans *tr
357364{
358365 struct nftables_pernet * nft_net = nft_pernet (net );
359366
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+
360375 list_add_tail (& trans -> list , & nft_net -> commit_list );
361376}
362377
@@ -9111,7 +9126,7 @@ static void nf_tables_trans_destroy_work(struct work_struct *w)
91119126 synchronize_rcu ();
91129127
91139128 list_for_each_entry_safe (trans , next , & head , list ) {
9114- list_del ( & trans -> list );
9129+ nft_trans_list_del ( trans );
91159130 nft_commit_release (trans );
91169131 }
91179132}
@@ -9476,6 +9491,19 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
94769491 return 0 ;
94779492 }
94789493
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+
94799507 /* 0. Validate ruleset, otherwise roll back for error reporting. */
94809508 if (nf_tables_validate (net ) < 0 )
94819509 return - EAGAIN ;
@@ -9989,7 +10017,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
998910017
999010018 list_for_each_entry_safe_reverse (trans , next ,
999110019 & nft_net -> commit_list , list ) {
9992- list_del ( & trans -> list );
10020+ nft_trans_list_del ( trans );
999310021 nf_tables_abort_release (trans );
999410022 }
999510023
@@ -10765,6 +10793,7 @@ static int __net_init nf_tables_init_net(struct net *net)
1076510793
1076610794 INIT_LIST_HEAD (& nft_net -> tables );
1076710795 INIT_LIST_HEAD (& nft_net -> commit_list );
10796+ INIT_LIST_HEAD (& nft_net -> binding_list );
1076810797 INIT_LIST_HEAD (& nft_net -> module_list );
1076910798 INIT_LIST_HEAD (& nft_net -> notify_list );
1077010799 mutex_init (& nft_net -> commit_mutex );
0 commit comments