mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-22 08:49:45 +00:00
netfilter: nftables: fix possible UAF over chains from packet path in netns
Although hooks are released via call_rcu(), chain and rule objects are immediately released while packets are still walking over these bits. This patch adds the .pre_exit callback which is invoked before synchronize_rcu() in the netns framework to stay safe. Remove a comment which is not valid anymore since the core does not use synchronize_net() anymore since8c873e2199
("netfilter: core: free hooks with call_rcu"). Suggested-by: Florian Westphal <fw@strlen.de> Fixes:df05ef874b
("netfilter: nf_tables: release objects on netns destruction") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
a3005b0f83
commit
767d1216bf
1 changed files with 19 additions and 6 deletions
|
@ -8949,6 +8949,17 @@ int __nft_release_basechain(struct nft_ctx *ctx)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(__nft_release_basechain);
|
||||
|
||||
static void __nft_release_hooks(struct net *net)
|
||||
{
|
||||
struct nft_table *table;
|
||||
struct nft_chain *chain;
|
||||
|
||||
list_for_each_entry(table, &net->nft.tables, list) {
|
||||
list_for_each_entry(chain, &table->chains, list)
|
||||
nf_tables_unregister_hook(net, table, chain);
|
||||
}
|
||||
}
|
||||
|
||||
static void __nft_release_tables(struct net *net)
|
||||
{
|
||||
struct nft_flowtable *flowtable, *nf;
|
||||
|
@ -8964,10 +8975,6 @@ static void __nft_release_tables(struct net *net)
|
|||
|
||||
list_for_each_entry_safe(table, nt, &net->nft.tables, list) {
|
||||
ctx.family = table->family;
|
||||
|
||||
list_for_each_entry(chain, &table->chains, list)
|
||||
nf_tables_unregister_hook(net, table, chain);
|
||||
/* No packets are walking on these chains anymore. */
|
||||
ctx.table = table;
|
||||
list_for_each_entry(chain, &table->chains, list) {
|
||||
ctx.chain = chain;
|
||||
|
@ -9016,6 +9023,11 @@ static int __net_init nf_tables_init_net(struct net *net)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void __net_exit nf_tables_pre_exit_net(struct net *net)
|
||||
{
|
||||
__nft_release_hooks(net);
|
||||
}
|
||||
|
||||
static void __net_exit nf_tables_exit_net(struct net *net)
|
||||
{
|
||||
mutex_lock(&net->nft.commit_mutex);
|
||||
|
@ -9029,8 +9041,9 @@ static void __net_exit nf_tables_exit_net(struct net *net)
|
|||
}
|
||||
|
||||
static struct pernet_operations nf_tables_net_ops = {
|
||||
.init = nf_tables_init_net,
|
||||
.exit = nf_tables_exit_net,
|
||||
.init = nf_tables_init_net,
|
||||
.pre_exit = nf_tables_pre_exit_net,
|
||||
.exit = nf_tables_exit_net,
|
||||
};
|
||||
|
||||
static int __init nf_tables_module_init(void)
|
||||
|
|
Loading…
Reference in a new issue