linux/net/sched
WANG Cong 4d97213d4f net_sched: invoke ->attach() after setting dev->qdisc
[ Upstream commit 86e363dc3b ]

For mq qdisc, we add per tx queue qdisc to root qdisc
for display purpose, however, that happens too early,
before the new dev->qdisc is finally set, this causes
q->list points to an old root qdisc which is going to be
freed right before assigning with a new one.

Fix this by moving ->attach() after setting dev->qdisc.

For the record, this fixes the following crash:

 ------------[ cut here ]------------
 WARNING: CPU: 1 PID: 975 at lib/list_debug.c:59 __list_del_entry+0x5a/0x98()
 list_del corruption. prev->next should be ffff8800d1998ae8, but was 6b6b6b6b6b6b6b6b
 CPU: 1 PID: 975 Comm: tc Not tainted 4.1.0-rc4+ #1019
 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
  0000000000000009 ffff8800d73fb928 ffffffff81a44e7f 0000000047574756
  ffff8800d73fb978 ffff8800d73fb968 ffffffff810790da ffff8800cfc4cd20
  ffffffff814e725b ffff8800d1998ae8 ffffffff82381250 0000000000000000
 Call Trace:
  [<ffffffff81a44e7f>] dump_stack+0x4c/0x65
  [<ffffffff810790da>] warn_slowpath_common+0x9c/0xb6
  [<ffffffff814e725b>] ? __list_del_entry+0x5a/0x98
  [<ffffffff81079162>] warn_slowpath_fmt+0x46/0x48
  [<ffffffff81820eb0>] ? dev_graft_qdisc+0x5e/0x6a
  [<ffffffff814e725b>] __list_del_entry+0x5a/0x98
  [<ffffffff814e72a7>] list_del+0xe/0x2d
  [<ffffffff81822f05>] qdisc_list_del+0x1e/0x20
  [<ffffffff81820cd1>] qdisc_destroy+0x30/0xd6
  [<ffffffff81822676>] qdisc_graft+0x11d/0x243
  [<ffffffff818233c1>] tc_get_qdisc+0x1a6/0x1d4
  [<ffffffff810b5eaf>] ? mark_lock+0x2e/0x226
  [<ffffffff817ff8f5>] rtnetlink_rcv_msg+0x181/0x194
  [<ffffffff817ff72e>] ? rtnl_lock+0x17/0x19
  [<ffffffff817ff72e>] ? rtnl_lock+0x17/0x19
  [<ffffffff817ff774>] ? __rtnl_unlock+0x17/0x17
  [<ffffffff81855dc6>] netlink_rcv_skb+0x4d/0x93
  [<ffffffff817ff756>] rtnetlink_rcv+0x26/0x2d
  [<ffffffff818544b2>] netlink_unicast+0xcb/0x150
  [<ffffffff81161db9>] ? might_fault+0x59/0xa9
  [<ffffffff81854f78>] netlink_sendmsg+0x4fa/0x51c
  [<ffffffff817d6e09>] sock_sendmsg_nosec+0x12/0x1d
  [<ffffffff817d8967>] sock_sendmsg+0x29/0x2e
  [<ffffffff817d8cf3>] ___sys_sendmsg+0x1b4/0x23a
  [<ffffffff8100a1b8>] ? native_sched_clock+0x35/0x37
  [<ffffffff810a1d83>] ? sched_clock_local+0x12/0x72
  [<ffffffff810a1fd4>] ? sched_clock_cpu+0x9e/0xb7
  [<ffffffff810def2a>] ? current_kernel_time+0xe/0x32
  [<ffffffff810b4bc5>] ? lock_release_holdtime.part.29+0x71/0x7f
  [<ffffffff810ddebf>] ? read_seqcount_begin.constprop.27+0x5f/0x76
  [<ffffffff810b6292>] ? trace_hardirqs_on_caller+0x17d/0x199
  [<ffffffff811b14d5>] ? __fget_light+0x50/0x78
  [<ffffffff817d9808>] __sys_sendmsg+0x42/0x60
  [<ffffffff817d9838>] SyS_sendmsg+0x12/0x1c
  [<ffffffff81a50e97>] system_call_fastpath+0x12/0x6f
 ---[ end trace ef29d3fb28e97ae7 ]---

For long term, we probably need to clean up the qdisc_graft() code
in case it hides other bugs like this.

Fixes: 95dc19299f ("pkt_sched: give visibility to mq slave qdiscs")
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2015-06-22 17:01:18 -07:00
..
act_api.c net: Use netlink_ns_capable to verify the permisions of netlink messages 2014-06-26 15:15:38 -04:00
act_csum.c net_sched: act: fetch hinfo from a->ops->hinfo 2014-01-21 14:43:16 -08:00
act_gact.c net_sched: act: fetch hinfo from a->ops->hinfo 2014-01-21 14:43:16 -08:00
act_ipt.c net_sched: act: fetch hinfo from a->ops->hinfo 2014-01-21 14:43:16 -08:00
act_mirred.c net_sched: act: fetch hinfo from a->ops->hinfo 2014-01-21 14:43:16 -08:00
act_nat.c net_sched: act: fetch hinfo from a->ops->hinfo 2014-01-21 14:43:16 -08:00
act_pedit.c net_sched: act: fetch hinfo from a->ops->hinfo 2014-01-21 14:43:16 -08:00
act_police.c net_sched: act: export tcf_hash_search() instead of tcf_hash_lookup() 2014-01-21 14:43:16 -08:00
act_simple.c net_sched: act: fetch hinfo from a->ops->hinfo 2014-01-21 14:43:16 -08:00
act_skbedit.c net_sched: act: fetch hinfo from a->ops->hinfo 2014-01-21 14:43:16 -08:00
cls_api.c net: Use netlink_ns_capable to verify the permisions of netlink messages 2014-06-26 15:15:38 -04:00
cls_basic.c net_sched: avoid casting void pointer 2014-01-13 11:50:15 -08:00
cls_bpf.c net_sched: add struct net pointer to tcf_proto_ops->dump 2014-01-13 11:50:14 -08:00
cls_cgroup.c net_sched: add struct net pointer to tcf_proto_ops->dump 2014-01-13 11:50:14 -08:00
cls_flow.c net_sched: add struct net pointer to tcf_proto_ops->dump 2014-01-13 11:50:14 -08:00
cls_fw.c net_sched: fix error return code in fw_change_attrs() 2014-01-16 19:12:03 -08:00
cls_route.c net_sched: avoid casting void pointer 2014-01-13 11:50:15 -08:00
cls_rsvp.c [NET_SCHED]: Remove unnecessary includes 2007-07-10 22:16:41 -07:00
cls_rsvp.h net_sched: add struct net pointer to tcf_proto_ops->dump 2014-01-13 11:50:14 -08:00
cls_rsvp6.c [NET_SCHED]: Remove unnecessary includes 2007-07-10 22:16:41 -07:00
cls_tcindex.c net_sched: fix an oops in tcindex filter 2014-05-31 13:20:39 -07:00
cls_u32.c net_sched: avoid casting void pointer 2014-01-13 11:50:15 -08:00
em_canid.c net: em_canid: Ematch rule to match CAN frames according to their identifiers 2012-07-04 13:07:05 +02:00
em_cmp.c net_sched: cleanups 2011-01-19 23:31:12 -08:00
em_ipset.c em_ipset: use dev_net() accessor 2013-10-18 16:23:06 -04:00
em_meta.c net: Change skb_get_rxhash to skb_get_hash 2013-12-17 16:36:21 -05:00
em_nbyte.c net_sched: cleanups 2011-01-19 23:31:12 -08:00
em_text.c net_sched: cleanups 2011-01-19 23:31:12 -08:00
em_u32.c net_sched: cleanups 2011-01-19 23:31:12 -08:00
ematch.c ematch: Fix auto-loading of ematch modules. 2015-03-18 13:31:21 +01:00
Kconfig net: pkt_sched: PIE AQM scheme 2014-01-06 15:13:01 -05:00
Makefile net: pkt_sched: PIE AQM scheme 2014-01-06 15:13:01 -05:00
sch_api.c net_sched: invoke ->attach() after setting dev->qdisc 2015-06-22 17:01:18 -07:00
sch_atm.c net_sched: info leak in atm_tc_dump_class() 2013-07-31 15:04:19 -07:00
sch_blackhole.c pkt_sched: Add qdisc->ops->peek() implementation. 2008-10-31 00:45:55 -07:00
sch_cbq.c net_sched: replace pr_warning with pr_warn 2013-12-31 13:50:56 -05:00
sch_choke.c random32: add prandom_u32_max and convert open coded users 2014-01-21 23:17:20 -08:00
sch_codel.c fq_codel: should use qdisc backlog as threshold 2012-05-16 15:30:26 -04:00
sch_drr.c net_sched: add 64bit rate estimators 2013-06-11 02:51:03 -07:00
sch_dsmark.c sch_dsmark: use correct func name in print messages 2013-12-31 13:50:57 -05:00
sch_fifo.c pkt_sched: Stop using NLA_PUT*(). 2012-04-01 18:11:37 -04:00
sch_fq.c pkt_sched: fq: do not hold qdisc lock while allocating memory 2014-03-10 16:17:52 -04:00
sch_fq_codel.c net: replace macros net_random and net_srandom with direct calls to prandom 2014-01-14 15:15:25 -08:00
sch_generic.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2014-01-14 14:42:42 -08:00
sch_gred.c net_sched: replace pr_warning with pr_warn 2013-12-31 13:50:56 -05:00
sch_hfsc.c net_sched: add 64bit rate estimators 2013-06-11 02:51:03 -07:00
sch_hhf.c net: sched: lock imbalance in hhf qdisc 2014-05-31 13:20:36 -07:00
sch_htb.c sch_htb: let skb->priority refer to non-leaf class 2014-01-22 17:39:48 -08:00
sch_ingress.c net_sched: factorize qdisc stats handling 2011-01-10 16:07:54 -08:00
sch_mq.c pkt_sched: give visibility to mq slave qdiscs 2013-12-09 19:54:47 -05:00
sch_mqprio.c pkt_sched: give visibility to mq slave qdiscs 2013-12-09 19:54:47 -05:00
sch_multiq.c net/*: Fix FSF address in file headers 2013-12-06 12:37:57 -05:00
sch_netem.c reciprocal_divide: update/correction of the algorithm 2014-01-21 23:17:20 -08:00
sch_pie.c net: sched: Cleanup PIE comments 2014-02-13 18:29:58 -05:00
sch_plug.c net_sched: sch_plug: plug_qdisc_ops is static 2012-02-13 16:04:40 -05:00
sch_prio.c pkt_sched: Stop using NLA_PUT*(). 2012-04-01 18:11:37 -04:00
sch_qfq.c pkt_sched: sch_qfq: remove a source of high packet delay/jitter 2013-07-18 13:02:00 -07:00
sch_red.c pkt_sched: Stop using NLA_PUT*(). 2012-04-01 18:11:37 -04:00
sch_sfb.c net: replace macros net_random and net_srandom with direct calls to prandom 2014-01-14 15:15:25 -08:00
sch_sfq.c net: replace macros net_random and net_srandom with direct calls to prandom 2014-01-14 15:15:25 -08:00
sch_tbf.c sch_tbf: Fix potential memory leak in tbf_change(). 2014-02-27 12:53:50 -05:00
sch_teql.c sch_teql: Convert over to dev_neigh_lookup_skb(). 2012-07-05 01:09:06 -07:00