From: Davide Caratti <dcaratti@redhat.com>
Date: Thu, 10 Jan 2019 20:21:02 +0100
Subject: net/sched: act_tunnel_key: fix memory leak in case of action replace
Git-commit: 9174c3df1cd181c14913138d50ccbe539bb08335
Patch-mainline: v5.0-rc3
References: networking-stable-19_01_26
running the following TDC test cases:
7afc - Replace tunnel_key set action with all parameters
364d - Replace tunnel_key set action with all parameters and cookie
it's possible to trigger kmemleak warnings like:
unreferenced object 0xffff94797127ab40 (size 192):
comm "tc", pid 3248, jiffies 4300565293 (age 1006.862s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 c0 93 f9 8a ff ff ff ff ................
41 84 ee 89 ff ff ff ff 00 00 00 00 00 00 00 00 A...............
backtrace:
[<000000001e85b61c>] tunnel_key_init+0x31d/0x820 [act_tunnel_key]
[<000000007f3f6ee7>] tcf_action_init_1+0x384/0x4c0
[<00000000e89e3ded>] tcf_action_init+0x12b/0x1a0
[<00000000c1c8c0f8>] tcf_action_add+0x73/0x170
[<0000000095a9fc28>] tc_ctl_action+0x122/0x160
[<000000004bebeac5>] rtnetlink_rcv_msg+0x263/0x2d0
[<000000009fd862dd>] netlink_rcv_skb+0x4a/0x110
[<00000000b55199e7>] netlink_unicast+0x1a0/0x250
[<000000004996cd21>] netlink_sendmsg+0x2c1/0x3c0
[<000000004d6a94b4>] sock_sendmsg+0x36/0x40
[<000000005d9f0208>] ___sys_sendmsg+0x280/0x2f0
[<00000000dec19023>] __sys_sendmsg+0x5e/0xa0
[<000000004b82ac81>] do_syscall_64+0x5b/0x180
[<00000000a0f1209a>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[<000000002926b2ab>] 0xffffffffffffffff
when the tunnel_key action is replaced, the kernel forgets to release the
dst metadata: ensure they are released by tunnel_key_init(), the same way
it's done in tunnel_key_release().
Fixes: d0f6dd8a914f4 ("net/sched: Introduce act_tunnel_key")
Signed-off-by: Davide Caratti <dcaratti@redhat.com>
Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
net/sched/act_tunnel_key.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
--- a/net/sched/act_tunnel_key.c
+++ b/net/sched/act_tunnel_key.c
@@ -70,6 +70,15 @@ static const struct nla_policy tunnel_ke
[TCA_TUNNEL_KEY_NO_CSUM] = { .type = NLA_U8 },
};
+static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
+{
+ if (!p)
+ return;
+ if (p->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
+ dst_release(&p->tcft_enc_metadata->dst);
+ kfree_rcu(p, rcu);
+}
+
static int tunnel_key_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a,
int ovr, int bind)
@@ -190,8 +199,7 @@ static int tunnel_key_init(struct net *n
rcu_assign_pointer(t->params, params_new);
- if (params_old)
- kfree_rcu(params_old, rcu);
+ tunnel_key_release_params(params_old);
if (ret == ACT_P_CREATED)
tcf_hash_insert(tn, *a);
@@ -210,12 +218,7 @@ static void tunnel_key_release(struct tc
struct tcf_tunnel_key_params *params;
params = rcu_dereference_protected(t->params, 1);
- if (params) {
- if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
- dst_release(¶ms->tcft_enc_metadata->dst);
-
- kfree_rcu(params, rcu);
- }
+ tunnel_key_release_params(params);
}
static int tunnel_key_dump_addresses(struct sk_buff *skb,