提交 9f8aac0b 编写于 作者: F Florian Westphal 提交者: Pablo Neira Ayuso

netfilter: nf_tables: fix memory leaks on chain rename

The new name is stored in the transaction metadata, on commit,
the pointers to the old and new names are swapped.

Therefore in abort and commit case we have to free the
pointer in the chain_trans container.

In commit case, the pointer can be used by another cpu that
is currently dumping the renamed chain, thus kfree needs to
happen after waiting for rcu readers to complete.

Fixes: b7263e07 ("netfilter: nf_tables: Allow chain name of up to 255 chars")
Signed-off-by: NFlorian Westphal <fw@strlen.de>
Signed-off-by: NPablo Neira Ayuso <pablo@netfilter.org>
上级 a12486eb
...@@ -6087,6 +6087,9 @@ static void nft_commit_release(struct nft_trans *trans) ...@@ -6087,6 +6087,9 @@ static void nft_commit_release(struct nft_trans *trans)
case NFT_MSG_DELTABLE: case NFT_MSG_DELTABLE:
nf_tables_table_destroy(&trans->ctx); nf_tables_table_destroy(&trans->ctx);
break; break;
case NFT_MSG_NEWCHAIN:
kfree(nft_trans_chain_name(trans));
break;
case NFT_MSG_DELCHAIN: case NFT_MSG_DELCHAIN:
nf_tables_chain_destroy(&trans->ctx); nf_tables_chain_destroy(&trans->ctx);
break; break;
...@@ -6316,13 +6319,15 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) ...@@ -6316,13 +6319,15 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
nf_tables_table_notify(&trans->ctx, NFT_MSG_DELTABLE); nf_tables_table_notify(&trans->ctx, NFT_MSG_DELTABLE);
break; break;
case NFT_MSG_NEWCHAIN: case NFT_MSG_NEWCHAIN:
if (nft_trans_chain_update(trans)) if (nft_trans_chain_update(trans)) {
nft_chain_commit_update(trans); nft_chain_commit_update(trans);
else nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
/* trans destroyed after rcu grace period */
} else {
nft_clear(net, trans->ctx.chain); nft_clear(net, trans->ctx.chain);
nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN); nft_trans_destroy(trans);
nft_trans_destroy(trans); }
break; break;
case NFT_MSG_DELCHAIN: case NFT_MSG_DELCHAIN:
nft_chain_del(trans->ctx.chain); nft_chain_del(trans->ctx.chain);
...@@ -6472,7 +6477,7 @@ static int __nf_tables_abort(struct net *net) ...@@ -6472,7 +6477,7 @@ static int __nf_tables_abort(struct net *net)
case NFT_MSG_NEWCHAIN: case NFT_MSG_NEWCHAIN:
if (nft_trans_chain_update(trans)) { if (nft_trans_chain_update(trans)) {
free_percpu(nft_trans_chain_stats(trans)); free_percpu(nft_trans_chain_stats(trans));
kfree(nft_trans_chain_name(trans));
nft_trans_destroy(trans); nft_trans_destroy(trans);
} else { } else {
trans->ctx.table->use--; trans->ctx.table->use--;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册