Commit 30e99ed6 authored by Wei Yongjun's avatar Wei Yongjun Committed by David S. Miller

net: sched: act_pedit: fix possible memory leak in tcf_pedit_init()

'keys_ex' is malloced by tcf_pedit_keys_ex_parse() in tcf_pedit_init()
but not all of the error handle path free it, this may cause memory
leak. This patch fix it.

Fixes: 71d0ed70 ("net/act_pedit: Support using offset relative to the conventional network headers")
Signed-off-by: default avatarWei Yongjun <weiyongjun1@huawei.com>
Acked-by: default avatarCong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7184e7e7
...@@ -175,32 +175,35 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, ...@@ -175,32 +175,35 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
if (!tcf_idr_check(tn, parm->index, a, bind)) { if (!tcf_idr_check(tn, parm->index, a, bind)) {
if (!parm->nkeys) { if (!parm->nkeys) {
NL_SET_ERR_MSG_MOD(extack, "Pedit requires keys to be passed"); NL_SET_ERR_MSG_MOD(extack, "Pedit requires keys to be passed");
return -EINVAL; ret = -EINVAL;
goto out_free;
} }
ret = tcf_idr_create(tn, parm->index, est, a, ret = tcf_idr_create(tn, parm->index, est, a,
&act_pedit_ops, bind, false); &act_pedit_ops, bind, false);
if (ret) if (ret)
return ret; goto out_free;
p = to_pedit(*a); p = to_pedit(*a);
keys = kmalloc(ksize, GFP_KERNEL); keys = kmalloc(ksize, GFP_KERNEL);
if (!keys) { if (!keys) {
tcf_idr_release(*a, bind); tcf_idr_release(*a, bind);
kfree(keys_ex); ret = -ENOMEM;
return -ENOMEM; goto out_free;
} }
ret = ACT_P_CREATED; ret = ACT_P_CREATED;
} else { } else {
if (bind) if (bind)
return 0; goto out_free;
tcf_idr_release(*a, bind); tcf_idr_release(*a, bind);
if (!ovr) if (!ovr) {
return -EEXIST; ret = -EEXIST;
goto out_free;
}
p = to_pedit(*a); p = to_pedit(*a);
if (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys) { if (p->tcfp_nkeys && p->tcfp_nkeys != parm->nkeys) {
keys = kmalloc(ksize, GFP_KERNEL); keys = kmalloc(ksize, GFP_KERNEL);
if (!keys) { if (!keys) {
kfree(keys_ex); ret = -ENOMEM;
return -ENOMEM; goto out_free;
} }
} }
} }
...@@ -222,6 +225,10 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, ...@@ -222,6 +225,10 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
if (ret == ACT_P_CREATED) if (ret == ACT_P_CREATED)
tcf_idr_insert(tn, *a); tcf_idr_insert(tn, *a);
return ret; return ret;
out_free:
kfree(keys_ex);
return ret;
} }
static void tcf_pedit_cleanup(struct tc_action *a) static void tcf_pedit_cleanup(struct tc_action *a)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment