[nf,1/2] netfilter: nf_tables: fix register ordering

Message ID 20180802194441.7441-2-fw@strlen.de
State Accepted
Delegated to: Pablo Neira
Headers show
Series
  • netfilter: nf_tables: fix register ordering
Related show

Commit Message

Florian Westphal Aug. 2, 2018, 7:44 p.m.
We must register nfnetlink ops last, as that exposes nf_tables to
userspace.  Without this, we could theoretically get nfnetlink request
before net->nft state has been initialized.

Fixes: 99633ab29b213 ("netfilter: nf_tables: complete net namespace support")
Signed-off-by: Florian Westphal <fw@strlen.de>
---
 net/netfilter/nf_tables_api.c | 34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)

Patch

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index f5745e4c6513..b0ddc7897ca8 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -7202,31 +7202,45 @@  static int __init nf_tables_module_init(void)
 {
 	int err;
 
-	nft_chain_filter_init();
+	err = register_pernet_subsys(&nf_tables_net_ops);
+	if (err < 0)
+		return err;
 
-	info = kmalloc_array(NFT_RULE_MAXEXPRS, sizeof(struct nft_expr_info),
-			     GFP_KERNEL);
-	if (info == NULL) {
-		err = -ENOMEM;
+	err = nft_chain_filter_init();
+	if (err < 0)
 		goto err1;
-	}
 
 	err = nf_tables_core_module_init();
 	if (err < 0)
 		goto err2;
 
-	err = nfnetlink_subsys_register(&nf_tables_subsys);
+	err = register_netdevice_notifier(&nf_tables_flowtable_notifier);
 	if (err < 0)
 		goto err3;
 
-	register_netdevice_notifier(&nf_tables_flowtable_notifier);
+	info = kmalloc_array(NFT_RULE_MAXEXPRS, sizeof(struct nft_expr_info),
+			     GFP_KERNEL);
+	if (info == NULL) {
+		err = -ENOMEM;
+		goto err4;
+	}
+
+	/* must be last */
+	err = nfnetlink_subsys_register(&nf_tables_subsys);
+	if (err < 0) {
+		kfree(info);
+		goto err4;
+	}
 
-	return register_pernet_subsys(&nf_tables_net_ops);
+	return err;
+err4:
+	unregister_netdevice_notifier(&nf_tables_flowtable_notifier);
 err3:
 	nf_tables_core_module_exit();
 err2:
-	kfree(info);
+	nft_chain_filter_fini();
 err1:
+	unregister_pernet_subsys(&nf_tables_net_ops);
 	return err;
 }