diff mbox

pkt_sched: Fix qdisc_create on stab error handling

Message ID 20090915184651.GA8373@ami.dom.local
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

Jarek Poplawski Sept. 15, 2009, 6:46 p.m. UTC
If qdisc_get_stab returns error in qdisc_create there is skipped qdisc
ops->destroy, which is necessary because it's after ops->init at the
moment, so memory leaks are quite probable.

Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
---

 net/sched/sch_api.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

David Miller Sept. 16, 2009, 6:42 a.m. UTC | #1
From: Jarek Poplawski <jarkao2@gmail.com>
Date: Tue, 15 Sep 2009 20:46:51 +0200

> If qdisc_get_stab returns error in qdisc_create there is skipped qdisc
> ops->destroy, which is necessary because it's after ops->init at the
> moment, so memory leaks are quite probable.
> 
> Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>

Applied, thanks a lot!
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 692d9a4..329be0c 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -804,7 +804,7 @@  qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
 			stab = qdisc_get_stab(tca[TCA_STAB]);
 			if (IS_ERR(stab)) {
 				err = PTR_ERR(stab);
-				goto err_out3;
+				goto err_out4;
 			}
 			sch->stab = stab;
 		}
@@ -833,7 +833,6 @@  qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
 		return sch;
 	}
 err_out3:
-	qdisc_put_stab(sch->stab);
 	dev_put(dev);
 	kfree((char *) sch - sch->padded);
 err_out2:
@@ -847,6 +846,7 @@  err_out4:
 	 * Any broken qdiscs that would require a ops->reset() here?
 	 * The qdisc was never in action so it shouldn't be necessary.
 	 */
+	qdisc_put_stab(sch->stab);
 	if (ops->destroy)
 		ops->destroy(sch);
 	goto err_out3;