OSDN Git Service

net/sched: act_tunnel_key: Fix double free dst_cache
authorwenxu <wenxu@ucloud.cn>
Tue, 5 Mar 2019 00:29:28 +0000 (08:29 +0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 5 Mar 2019 20:57:28 +0000 (12:57 -0800)
dst_cache_destroy will be called in dst_release

dst_release-->dst_destroy_rcu-->dst_destroy-->metadata_dst_free
-->dst_cache_destroy

It should not call dst_cache_destroy before dst_release

Fixes: 41411e2fd6b8 ("net/sched: act_tunnel_key: Add dst_cache support")
Signed-off-by: wenxu <wenxu@ucloud.cn>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/sched/act_tunnel_key.c

index 3beb471..7c6591b 100644 (file)
@@ -201,14 +201,9 @@ static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
 {
        if (!p)
                return;
-       if (p->tcft_action == TCA_TUNNEL_KEY_ACT_SET) {
-#ifdef CONFIG_DST_CACHE
-               struct ip_tunnel_info *info = &p->tcft_enc_metadata->u.tun_info;
-
-               dst_cache_destroy(&info->dst_cache);
-#endif
+       if (p->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
                dst_release(&p->tcft_enc_metadata->dst);
-       }
+
        kfree_rcu(p, rcu);
 }
 
@@ -338,7 +333,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
                                                  &metadata->u.tun_info,
                                                  opts_len, extack);
                        if (ret < 0)
-                               goto release_dst_cache;
+                               goto release_tun_meta;
                }
 
                metadata->u.tun_info.mode |= IP_TUNNEL_INFO_TX;
@@ -354,14 +349,14 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
                                     &act_tunnel_key_ops, bind, true);
                if (ret) {
                        NL_SET_ERR_MSG(extack, "Cannot create TC IDR");
-                       goto release_dst_cache;
+                       goto release_tun_meta;
                }
 
                ret = ACT_P_CREATED;
        } else if (!ovr) {
                NL_SET_ERR_MSG(extack, "TC IDR already exists");
                ret = -EEXIST;
-               goto release_dst_cache;
+               goto release_tun_meta;
        }
 
        t = to_tunnel_key(*a);
@@ -371,7 +366,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
                NL_SET_ERR_MSG(extack, "Cannot allocate tunnel key parameters");
                ret = -ENOMEM;
                exists = true;
-               goto release_dst_cache;
+               goto release_tun_meta;
        }
        params_new->tcft_action = parm->t_action;
        params_new->tcft_enc_metadata = metadata;
@@ -388,12 +383,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
 
        return ret;
 
-release_dst_cache:
-#ifdef CONFIG_DST_CACHE
-       if (metadata)
-               dst_cache_destroy(&metadata->u.tun_info.dst_cache);
 release_tun_meta:
-#endif
        if (metadata)
                dst_release(&metadata->dst);