Skip to content

Commit

Permalink
netfilter: nf_tables: fix memory leaks on chain rename
Browse files Browse the repository at this point in the history
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: b7263e0 ("netfilter: nf_tables: Allow chain name of up to 255 chars")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Florian Westphal authored and Pablo Neira Ayuso committed Jul 20, 2018
1 parent a12486e commit 9f8aac0
Showing 1 changed file with 11 additions and 6 deletions.
17 changes: 11 additions & 6 deletions net/netfilter/nf_tables_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -6087,6 +6087,9 @@ static void nft_commit_release(struct nft_trans *trans)
case NFT_MSG_DELTABLE:
nf_tables_table_destroy(&trans->ctx);
break;
case NFT_MSG_NEWCHAIN:
kfree(nft_trans_chain_name(trans));
break;
case NFT_MSG_DELCHAIN:
nf_tables_chain_destroy(&trans->ctx);
break;
Expand Down Expand Up @@ -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);
break;
case NFT_MSG_NEWCHAIN:
if (nft_trans_chain_update(trans))
if (nft_trans_chain_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);

nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
nft_trans_destroy(trans);
nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
nft_trans_destroy(trans);
}
break;
case NFT_MSG_DELCHAIN:
nft_chain_del(trans->ctx.chain);
Expand Down Expand Up @@ -6472,7 +6477,7 @@ static int __nf_tables_abort(struct net *net)
case NFT_MSG_NEWCHAIN:
if (nft_trans_chain_update(trans)) {
free_percpu(nft_trans_chain_stats(trans));

kfree(nft_trans_chain_name(trans));
nft_trans_destroy(trans);
} else {
trans->ctx.table->use--;
Expand Down

0 comments on commit 9f8aac0

Please sign in to comment.