Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nf_tables: fix register ordering

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>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
d209df3e 3e673b23

+25 -10
+1 -1
include/net/netfilter/nf_tables.h
··· 1374 1374 (((struct nft_trans_flowtable *)trans->data)->flowtable) 1375 1375 1376 1376 int __init nft_chain_filter_init(void); 1377 - void __exit nft_chain_filter_fini(void); 1377 + void nft_chain_filter_fini(void); 1378 1378 1379 1379 #endif /* _NET_NF_TABLES_H */
+23 -8
net/netfilter/nf_tables_api.c
··· 7273 7273 { 7274 7274 int err; 7275 7275 7276 - nft_chain_filter_init(); 7277 - 7278 - err = nf_tables_core_module_init(); 7276 + err = register_pernet_subsys(&nf_tables_net_ops); 7279 7277 if (err < 0) 7280 7278 return err; 7281 7279 7280 + err = nft_chain_filter_init(); 7281 + if (err < 0) 7282 + goto err1; 7283 + 7284 + err = nf_tables_core_module_init(); 7285 + if (err < 0) 7286 + goto err2; 7287 + 7288 + err = register_netdevice_notifier(&nf_tables_flowtable_notifier); 7289 + if (err < 0) 7290 + goto err3; 7291 + 7292 + /* must be last */ 7282 7293 err = nfnetlink_subsys_register(&nf_tables_subsys); 7283 7294 if (err < 0) 7284 - goto err; 7295 + goto err4; 7285 7296 7286 - register_netdevice_notifier(&nf_tables_flowtable_notifier); 7287 - 7288 - return register_pernet_subsys(&nf_tables_net_ops); 7289 - err: 7297 + return err; 7298 + err4: 7299 + unregister_netdevice_notifier(&nf_tables_flowtable_notifier); 7300 + err3: 7290 7301 nf_tables_core_module_exit(); 7302 + err2: 7303 + nft_chain_filter_fini(); 7304 + err1: 7305 + unregister_pernet_subsys(&nf_tables_net_ops); 7291 7306 return err; 7292 7307 } 7293 7308
+1 -1
net/netfilter/nft_chain_filter.c
··· 392 392 return 0; 393 393 } 394 394 395 - void __exit nft_chain_filter_fini(void) 395 + void nft_chain_filter_fini(void) 396 396 { 397 397 nft_chain_filter_bridge_fini(); 398 398 nft_chain_filter_inet_fini();