[Devel] [PATCH RHEL7 COMMIT] ms/netfilter: nf_tables: fix memory leaks on chain rename

Konstantin Khorenko khorenko at virtuozzo.com
Mon Sep 5 14:58:05 MSK 2022


The commit is pushed to "branch-rh7-3.10.0-1160.76.1.vz7.189.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.76.1.vz7.189.1
------>
commit 41dbf6f4f55933c3249c591f4df4b8ebeddb9cb3
Author: Florian Westphal <fw at strlen.de>
Date:   Tue Jul 17 07:17:55 2018 +0200

    ms/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.
    
    mFixes: b7263e071a ("netfilter: nf_tables: Allow chain name of up to 255 chars")
    Signed-off-by: Florian Westphal <fw at strlen.de>
    Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
    
    (cherry picked from ms commit 9f8aac0be21ed5f99bd5ba0ff315d710737d1794)
    Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
 net/netfilter/nf_tables_api.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index a231a67d62c07..f5526bd2a435c 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -4090,6 +4090,9 @@ static void nf_tables_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.chain);
 		break;
@@ -4145,13 +4148,15 @@ static int nf_tables_commit(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:
 			list_del_rcu(&trans->ctx.chain->list);
@@ -4276,7 +4281,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--;


More information about the Devel mailing list