diff options
| author | Hiroaki SHIMODA <shimoda.hiroaki@gmail.com> | 2014-02-26 21:43:42 +0900 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-02-27 12:53:50 -0500 | 
| commit | 724b9e1d75ab3401aaa081bd4efb440c1b3509db (patch) | |
| tree | ad5545d23ed048dc2576eb8537446c3ccc421003 | |
| parent | 09a89c219baf0f116387efc928e325cf23630f20 (diff) | |
sch_tbf: Fix potential memory leak in tbf_change().
The allocated child qdisc is not freed in error conditions.
Defer the allocation after user configuration turns out to be
valid and acceptable.
Fixes: cc106e441a63b ("net: sched: tbf: fix the calculation of max_size")
Signed-off-by: Hiroaki SHIMODA <shimoda.hiroaki@gmail.com>
Cc: Yang Yingliang <yangyingliang@huawei.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/sched/sch_tbf.c | 24 | 
1 files changed, 12 insertions, 12 deletions
| diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index 1cb413fead89..4f505a006896 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c @@ -334,18 +334,6 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)  			qdisc_put_rtab(qdisc_get_rtab(&qopt->peakrate,  						      tb[TCA_TBF_PTAB])); -	if (q->qdisc != &noop_qdisc) { -		err = fifo_set_limit(q->qdisc, qopt->limit); -		if (err) -			goto done; -	} else if (qopt->limit > 0) { -		child = fifo_create_dflt(sch, &bfifo_qdisc_ops, qopt->limit); -		if (IS_ERR(child)) { -			err = PTR_ERR(child); -			goto done; -		} -	} -  	buffer = min_t(u64, PSCHED_TICKS2NS(qopt->buffer), ~0U);  	mtu = min_t(u64, PSCHED_TICKS2NS(qopt->mtu), ~0U); @@ -390,6 +378,18 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)  		goto done;  	} +	if (q->qdisc != &noop_qdisc) { +		err = fifo_set_limit(q->qdisc, qopt->limit); +		if (err) +			goto done; +	} else if (qopt->limit > 0) { +		child = fifo_create_dflt(sch, &bfifo_qdisc_ops, qopt->limit); +		if (IS_ERR(child)) { +			err = PTR_ERR(child); +			goto done; +		} +	} +  	sch_tree_lock(sch);  	if (child) {  		qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen); | 
