[RHEL7,COMMIT] ms/netfilter: nf_tables: avoid global info storage

Submitted by Konstantin Khorenko on Oct. 18, 2019, 12:28 p.m.

Details

Message ID 201910181228.x9ICSNgu003829@finist-ce7.sw.ru
State New
Series "ms/netfilter: nf_tables: avoid global info storage"
Headers show

Commit Message

Konstantin Khorenko Oct. 18, 2019, 12:28 p.m.
The commit is pushed to "branch-rh7-3.10.0-1062.1.2.vz7.114.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1062.1.2.vz7.114.7
------>
commit e54d6e25df68446014330beda681a9cecaff9942
Author: Vasily Averin <vvs@virtuozzo.com>
Date:   Fri Oct 18 15:28:23 2019 +0300

    ms/netfilter: nf_tables: avoid global info storage
    
    ML commit 2a43ecf96ba6a6eed70dbcd99d0888fc0ad3b82b
    Author: Florian Westphal <fw@strlen.de>
    Date:   Wed Jul 11 13:45:13 2018 +0200
    
        netfilter: nf_tables: avoid global info storage
    
    This works because all accesses are currently serialized by nfnl
    nf_tables subsys mutex.
    
    If we want to have per-netns locking, we need to make this scratch
    area pernetns or allocate it on demand.
    
    This does the latter, its ~28kbyte but we can fallback to vmalloc
    so it should be fine.
    
    Signed-off-by: Florian Westphal <fw@strlen.de>
    Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
    
    VvS: backported to vz7.114.x kernels to fix high-order-allocation warning
    https://jira.sw.ru/browse/PSBM-98682
    Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
---
 net/netfilter/nf_tables_api.c | 28 ++++++++++++----------------
 1 file changed, 12 insertions(+), 16 deletions(-)

Patch hide | download patch | download mbox

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index c80cc26b090b..1e75d13abab6 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2022,14 +2022,13 @@  static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
 
 #define NFT_RULE_MAXEXPRS	128
 
-static struct nft_expr_info *info;
-
 static int nf_tables_newrule(struct net *net, struct sock *nlsk,
 			     struct sk_buff *skb, const struct nlmsghdr *nlh,
 			     const struct nlattr * const nla[])
 {
 	const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
 	struct nft_af_info *afi;
+	struct nft_expr_info *info = NULL;
 	struct nft_table *table;
 	struct nft_chain *chain;
 	struct nft_rule *rule, *old_rule = NULL;
@@ -2093,6 +2092,12 @@  static int nf_tables_newrule(struct net *net, struct sock *nlsk,
 	n = 0;
 	size = 0;
 	if (nla[NFTA_RULE_EXPRESSIONS]) {
+		info = kvmalloc_array(NFT_RULE_MAXEXPRS,
+				      sizeof(struct nft_expr_info),
+				      GFP_KERNEL);
+		if (!info)
+			return -ENOMEM;
+
 		nla_for_each_nested(tmp, nla[NFTA_RULE_EXPRESSIONS], rem) {
 			err = -EINVAL;
 			if (nla_type(tmp) != NFTA_LIST_ELEM)
@@ -2174,6 +2179,7 @@  static int nf_tables_newrule(struct net *net, struct sock *nlsk,
 		err = -ENOMEM;
 		goto err3;
 	}
+	kvfree(info);
 	chain->use++;
 	return 0;
 
@@ -2186,6 +2192,7 @@  static int nf_tables_newrule(struct net *net, struct sock *nlsk,
 		if (info[i].ops != NULL)
 			module_put(info[i].ops->type->owner);
 	}
+	kvfree(info);
 	return err;
 }
 
@@ -4735,28 +4742,18 @@  static int __init nf_tables_module_init(void)
 {
 	int err;
 
-	info = kmalloc(sizeof(struct nft_expr_info) * NFT_RULE_MAXEXPRS,
-		       GFP_KERNEL);
-	if (info == NULL) {
-		err = -ENOMEM;
-		goto err1;
-	}
-
 	err = nf_tables_core_module_init();
 	if (err < 0)
-		goto err2;
+		return err;
 
 	err = nfnetlink_subsys_register(&nf_tables_subsys);
 	if (err < 0)
-		goto err3;
+		goto err;
 
 	pr_info("nf_tables: (c) 2007-2009 Patrick McHardy <kaber@trash.net>\n");
 	return register_pernet_subsys(&nf_tables_net_ops);
-err3:
+err:
 	nf_tables_core_module_exit();
-err2:
-	kfree(info);
-err1:
 	return err;
 }
 
@@ -4766,7 +4763,6 @@  static void __exit nf_tables_module_exit(void)
 	nfnetlink_subsys_unregister(&nf_tables_subsys);
 	rcu_barrier();
 	nf_tables_core_module_exit();
-	kfree(info);
 }
 
 module_init(nf_tables_module_init);