[PATCH 4.14 145/496] netfilter: ipt_CLUSTERIP: put config instead of freeing it

From: Greg Kroah-Hartman
Date: Mon May 28 2018 - 09:21:30 EST


4.14-stable review patch. If anyone has any objections, please let me know.

------------------

From: Florian Westphal <fw@xxxxxxxxx>

[ Upstream commit 1a9da5937386dbe553ffcf6c65d985bd48c347c5 ]

Once struct is added to per-netns list it becomes visible to other cpus,
so we cannot use kfree().

Also delay setting entries refcount to 1 until after everything is
initialised so that when we call clusterip_config_put() in this spot
entries is still zero.

Signed-off-by: Florian Westphal <fw@xxxxxxxxx>
Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
Signed-off-by: Sasha Levin <alexander.levin@xxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
net/ipv4/netfilter/ipt_CLUSTERIP.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -228,7 +228,6 @@ clusterip_config_init(struct net *net, c
c->hash_mode = i->hash_mode;
c->hash_initval = i->hash_initval;
refcount_set(&c->refcount, 1);
- refcount_set(&c->entries, 1);

spin_lock_bh(&cn->lock);
if (__clusterip_config_find(net, ip)) {
@@ -259,8 +258,10 @@ clusterip_config_init(struct net *net, c

c->notifier.notifier_call = clusterip_netdev_event;
err = register_netdevice_notifier(&c->notifier);
- if (!err)
+ if (!err) {
+ refcount_set(&c->entries, 1);
return c;
+ }

#ifdef CONFIG_PROC_FS
proc_remove(c->pde);
@@ -269,7 +270,7 @@ err:
spin_lock_bh(&cn->lock);
list_del_rcu(&c->list);
spin_unlock_bh(&cn->lock);
- kfree(c);
+ clusterip_config_put(c);

return ERR_PTR(err);
}