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, ...@@ -352,7 +352,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
return res; return res;
out: out:
if (res == ACT_P_CREATED) if (res == ACT_P_CREATED)
tcf_idr_cleanup(*act, est); tcf_idr_release(*act, bind);
return ret; return ret;
} }
......
...@@ -80,9 +80,12 @@ static void ipt_destroy_target(struct xt_entry_target *t) ...@@ -80,9 +80,12 @@ static void ipt_destroy_target(struct xt_entry_target *t)
static void tcf_ipt_release(struct tc_action *a) static void tcf_ipt_release(struct tc_action *a)
{ {
struct tcf_ipt *ipt = to_ipt(a); struct tcf_ipt *ipt = to_ipt(a);
ipt_destroy_target(ipt->tcfi_t);
if (ipt->tcfi_t) {
ipt_destroy_target(ipt->tcfi_t);
kfree(ipt->tcfi_t);
}
kfree(ipt->tcfi_tname); kfree(ipt->tcfi_tname);
kfree(ipt->tcfi_t);
} }
static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = { 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, ...@@ -187,7 +190,7 @@ static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla,
kfree(tname); kfree(tname);
err1: err1:
if (ret == ACT_P_CREATED) if (ret == ACT_P_CREATED)
tcf_idr_cleanup(*a, est); tcf_idr_release(*a, bind);
return err; return err;
} }
......
...@@ -176,7 +176,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, ...@@ -176,7 +176,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
p = to_pedit(*a); p = to_pedit(*a);
keys = kmalloc(ksize, GFP_KERNEL); keys = kmalloc(ksize, GFP_KERNEL);
if (keys == NULL) { if (keys == NULL) {
tcf_idr_cleanup(*a, est); tcf_idr_release(*a, bind);
kfree(keys_ex); kfree(keys_ex);
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -194,7 +194,7 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla, ...@@ -194,7 +194,7 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla,
qdisc_put_rtab(P_tab); qdisc_put_rtab(P_tab);
qdisc_put_rtab(R_tab); qdisc_put_rtab(R_tab);
if (ret == ACT_P_CREATED) if (ret == ACT_P_CREATED)
tcf_idr_cleanup(*a, est); tcf_idr_release(*a, bind);
return err; return err;
} }
......
...@@ -121,7 +121,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, ...@@ -121,7 +121,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
d = to_defact(*a); d = to_defact(*a);
ret = alloc_defdata(d, defdata); ret = alloc_defdata(d, defdata);
if (ret < 0) { if (ret < 0) {
tcf_idr_cleanup(*a, est); tcf_idr_release(*a, bind);
return ret; return ret;
} }
d->tcf_action = parm->action; d->tcf_action = parm->action;
......
...@@ -152,7 +152,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, ...@@ -152,7 +152,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
ASSERT_RTNL(); ASSERT_RTNL();
p = kzalloc(sizeof(struct tcf_skbmod_params), GFP_KERNEL); p = kzalloc(sizeof(struct tcf_skbmod_params), GFP_KERNEL);
if (unlikely(!p)) { if (unlikely(!p)) {
if (ovr) if (ret == ACT_P_CREATED)
tcf_idr_release(*a, bind); tcf_idr_release(*a, bind);
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -195,7 +195,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, ...@@ -195,7 +195,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
ASSERT_RTNL(); ASSERT_RTNL();
p = kzalloc(sizeof(*p), GFP_KERNEL); p = kzalloc(sizeof(*p), GFP_KERNEL);
if (!p) { if (!p) {
if (ovr) if (ret == ACT_P_CREATED)
tcf_idr_release(*a, bind); tcf_idr_release(*a, bind);
return -ENOMEM; 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