linux/net/sched
WANG Cong ba55aba5bd net_sched: invoke ->attach() after setting dev->qdisc
commit 86e363dc3b upstream.

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: Luis Henriques <luis.henriques@canonical.com>
History 2015-06-03 14:30:07 +01:00
..
act_api.c net: Use netlink_ns_capable to verify the permisions of netlink messages 2014-04-24 13:44:54 -04:00
act_csum.c net_sched: act: move tcf_hashinfo_init() into tcf_register_action() 2014-02-12 19:23:32 -05:00
act_gact.c net_sched: act: move tcf_hashinfo_init() into tcf_register_action() 2014-02-12 19:23:32 -05:00
act_ipt.c net_sched: act: move tcf_hashinfo_init() into tcf_register_action() 2014-02-12 19:23:32 -05:00
act_mirred.c net_sched: act: move tcf_hashinfo_init() into tcf_register_action() 2014-02-12 19:23:32 -05:00
act_nat.c net_sched: act: move tcf_hashinfo_init() into tcf_register_action() 2014-02-12 19:23:32 -05:00
act_pedit.c net_sched: act: move tcf_hashinfo_init() into tcf_register_action() 2014-02-12 19:23:32 -05:00
act_police.c net_sched: act: move tcf_hashinfo_init() into tcf_register_action() 2014-02-12 19:23:32 -05:00
act_simple.c net_sched: act: move tcf_hashinfo_init() into tcf_register_action() 2014-02-12 19:23:32 -05:00
act_skbedit.c net_sched: act: move tcf_hashinfo_init() into tcf_register_action() 2014-02-12 19:23:32 -05:00
cls_api.c net_sched: copy exts->type in tcf_exts_change() 2014-10-15 12:05:30 +02:00
cls_basic.c sched, cls: check if we could overwrite actions when changing a filter 2014-04-27 23:42:39 -04:00
cls_bpf.c net: cls_bpf: fix auto generation of per list handles 2015-03-20 09:36:24 +00:00
cls_cgroup.c sched, cls: check if we could overwrite actions when changing a filter 2014-04-27 23:42:39 -04:00
cls_flow.c sched, cls: check if we could overwrite actions when changing a filter 2014-04-27 23:42:39 -04:00
cls_fw.c sched, cls: check if we could overwrite actions when changing a filter 2014-04-27 23:42:39 -04:00
cls_route.c sched, cls: check if we could overwrite actions when changing a filter 2014-04-27 23:42:39 -04:00
cls_rsvp.c [NET_SCHED]: Remove unnecessary includes 2007-07-10 22:16:41 -07:00
cls_rsvp.h sched, cls: check if we could overwrite actions when changing a filter 2014-04-27 23:42:39 -04:00
cls_rsvp6.c [NET_SCHED]: Remove unnecessary includes 2007-07-10 22:16:41 -07:00
cls_tcindex.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2014-05-24 00:32:30 -04:00
cls_u32.c net_sched: avoid generating same handle for u32 filters 2014-07-20 20:49:17 -07: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-12 16:27:28 +00: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-03 14:30:07 +01:00
sch_atm.c net_sched: return nla_nest_end() instead of skb->len 2014-03-13 15:39:20 -04:00
sch_blackhole.c pkt_sched: Add qdisc->ops->peek() implementation. 2008-10-31 00:45:55 -07:00
sch_cbq.c net_sched: return nla_nest_end() instead of skb->len 2014-03-13 15:39:20 -04:00
sch_choke.c net: use the new API kvfree() 2014-06-05 00:49:51 -07: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: drr: warn when qdisc is not work conserving 2014-06-11 15:50:59 -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 net: use the new API kvfree() 2014-06-05 00:49:51 -07:00
sch_fq_codel.c net: use the new API kvfree() 2014-06-05 00:49:51 -07:00
sch_generic.c net-sysfs: expose number of carrier on/off changes 2014-03-31 16:24:52 -04: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: return nla_nest_end() instead of skb->len 2014-03-13 15:39:20 -04:00
sch_hhf.c net: use the new API kvfree() 2014-06-05 00:49:51 -07:00
sch_htb.c net_sched: htb: do not acquire qdisc lock in dump operations 2014-03-06 17:24:54 -05:00
sch_ingress.c net_sched: return nla_nest_end() instead of skb->len 2014-03-13 15:39:20 -04: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 net: use the new API kvfree() 2014-06-05 00:49:51 -07: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: use the new API kvfree() 2014-06-05 00:49:51 -07:00
sch_tbf.c net_sched: return nla_nest_end() instead of skb->len 2014-03-13 15:39:20 -04:00
sch_teql.c sch_teql: Convert over to dev_neigh_lookup_skb(). 2012-07-05 01:09:06 -07:00