diff options
author | Eric Dumazet <edumazet@google.com> | 2016-08-24 12:39:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-08-25 19:44:20 -0400 |
commit | 166ee5b87866de07a3e56c1b757f2b5cabba72a5 (patch) | |
tree | 4914730f1ac8cf84c32c36fb10a3c3b67778639c | |
parent | a5de125dd46c851fc962806135953c1bd0a0f0df (diff) |
qdisc: fix a module refcount leak in qdisc_create_dflt()
Should qdisc_alloc() fail, we must release the module refcount
we got right before.
Fixes: 6da7c8fcbcbd ("qdisc: allow setting default queuing discipline")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: John Fastabend <john.r.fastabend@intel.com>
Acked-by: John Fastabend <john.r.fastabend@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/sched/sch_generic.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index e95b67cd5718..657c13362b19 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -643,18 +643,19 @@ struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue, | |||
643 | struct Qdisc *sch; | 643 | struct Qdisc *sch; |
644 | 644 | ||
645 | if (!try_module_get(ops->owner)) | 645 | if (!try_module_get(ops->owner)) |
646 | goto errout; | 646 | return NULL; |
647 | 647 | ||
648 | sch = qdisc_alloc(dev_queue, ops); | 648 | sch = qdisc_alloc(dev_queue, ops); |
649 | if (IS_ERR(sch)) | 649 | if (IS_ERR(sch)) { |
650 | goto errout; | 650 | module_put(ops->owner); |
651 | return NULL; | ||
652 | } | ||
651 | sch->parent = parentid; | 653 | sch->parent = parentid; |
652 | 654 | ||
653 | if (!ops->init || ops->init(sch, NULL) == 0) | 655 | if (!ops->init || ops->init(sch, NULL) == 0) |
654 | return sch; | 656 | return sch; |
655 | 657 | ||
656 | qdisc_destroy(sch); | 658 | qdisc_destroy(sch); |
657 | errout: | ||
658 | return NULL; | 659 | return NULL; |
659 | } | 660 | } |
660 | EXPORT_SYMBOL(qdisc_create_dflt); | 661 | EXPORT_SYMBOL(qdisc_create_dflt); |