Commit ba9a1908 authored by David S. Miller's avatar David S. Miller

Merge branch 'net-sched-action-idr-leak'

Davide Caratti says:

====================
fix idr leak in actions

This series fixes situations where a temporary failure to install a TC
action results in the permanent impossibility to reuse the configured
value of 'index'.

Thanks to Cong Wang for the initial review.

v2: fix build error in act_ipt.c, reported by kbuild test robot
====================
Acked-by: default avatarCong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 3f2176dd f29cdfbe
......@@ -352,7 +352,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
return res;
out:
if (res == ACT_P_CREATED)
tcf_idr_cleanup(*act, est);
tcf_idr_release(*act, bind);
return ret;
}
......
......@@ -80,9 +80,12 @@ static void ipt_destroy_target(struct xt_entry_target *t)
static void tcf_ipt_release(struct tc_action *a)
{
struct tcf_ipt *ipt = to_ipt(a);
if (ipt->tcfi_t) {
ipt_destroy_target(ipt->tcfi_t);
kfree(ipt->tcfi_tname);
kfree(ipt->tcfi_t);
}
kfree(ipt->tcfi_tname);
}
static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = {
......@@ -187,7 +190,7 @@ static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla,
kfree(tname);
err1:
if (ret == ACT_P_CREATED)
tcf_idr_cleanup(*a, est);
tcf_idr_release(*a, bind);
return err;
}
......
......@@ -176,7 +176,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
p = to_pedit(*a);
keys = kmalloc(ksize, GFP_KERNEL);
if (keys == NULL) {
tcf_idr_cleanup(*a, est);
tcf_idr_release(*a, bind);
kfree(keys_ex);
return -ENOMEM;
}
......
......@@ -194,7 +194,7 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla,
qdisc_put_rtab(P_tab);
qdisc_put_rtab(R_tab);
if (ret == ACT_P_CREATED)
tcf_idr_cleanup(*a, est);
tcf_idr_release(*a, bind);
return err;
}
......
......@@ -121,7 +121,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
d = to_defact(*a);
ret = alloc_defdata(d, defdata);
if (ret < 0) {
tcf_idr_cleanup(*a, est);
tcf_idr_release(*a, bind);
return ret;
}
d->tcf_action = parm->action;
......
......@@ -152,7 +152,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
ASSERT_RTNL();
p = kzalloc(sizeof(struct tcf_skbmod_params), GFP_KERNEL);
if (unlikely(!p)) {
if (ovr)
if (ret == ACT_P_CREATED)
tcf_idr_release(*a, bind);
return -ENOMEM;
}
......
......@@ -195,7 +195,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
ASSERT_RTNL();
p = kzalloc(sizeof(*p), GFP_KERNEL);
if (!p) {
if (ovr)
if (ret == ACT_P_CREATED)
tcf_idr_release(*a, bind);
return -ENOMEM;
}
......
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