mirror-linux/net/sched
Jamal Hadi Salim 320fb29ea2 net/sched: sch_cbs: Call qdisc_reset for child qdisc
During a reset, CBS is not calling reset on its child qdisc, which
might cause qlen/backlog accounting issues. For example, if we have CBS
with a QFQ parent and a netem child with delay, we can create a scenario
where the parent's qlen underflows. QFQ, specifically, uses qlen to
check whether it should deference a pointer, so this scenario may cause
a null-ptr deref in QFQ:

[   43.875639][  T319] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000009: 0000 [#1] SMP KASAN NOPTI
[   43.876124][  T319] KASAN: null-ptr-deref in range [0x0000000000000048-0x000000000000004f]
[   43.876417][  T319] CPU: 10 UID: 0 PID: 319 Comm: ping Not tainted 7.0.0-13039-ge728258debd5 #773 PREEMPT(full)
[   43.876751][  T319] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[   43.876949][  T319] RIP: 0010:qfq_dequeue+0x35c/0x1650
[   43.877123][  T319] Code: 00 fc ff df 80 3c 02 00 0f 85 17 0e 00 00 4c 8d 73 48 48 89 9d b8 02 00 00 48 b8 00 00 00 00 00 fc ff df 4c 89 f2 48 c1 ea 03 <80> 3c 02 00 0f 85 76 0c 00 00 48 b8 00 00 00 00 00 fc ff df 4c 8b
[   43.877648][  T319] RSP: 0018:ffff8881017ef4f0 EFLAGS: 00010216
[   43.877845][  T319] RAX: dffffc0000000000 RBX: 0000000000000000 RCX: dffffc0000000000
[   43.878073][  T319] RDX: 0000000000000009 RSI: 0000000c40000000 RDI: ffff88810eef02b0
[   43.878306][  T319] RBP: ffff88810eef0000 R08: ffff88810eef0280 R09: 1ffff1102120fd63
[   43.878523][  T319] R10: 1ffff1102120fd66 R11: 1ffff1102120fd67 R12: 0000000c40000000
[   43.878742][  T319] R13: ffff88810eef02b8 R14: 0000000000000048 R15: 0000000020000000
[   43.878959][  T319] FS:  00007f9c51c47c40(0000) GS:ffff88817a0be000(0000) knlGS:0000000000000000
[   43.879214][  T319] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   43.879403][  T319] CR2: 000055e69a2230a8 CR3: 000000010c07a000 CR4: 0000000000750ef0
[   43.879621][  T319] PKRU: 55555554
[   43.879735][  T319] Call Trace:
[   43.879844][  T319]  <TASK>
[   43.879924][  T319]  __qdisc_run+0x169/0x1900
[   43.880075][  T319]  ? dev_qdisc_enqueue+0x8b/0x210
[   43.880222][  T319]  __dev_queue_xmit+0x2346/0x37a0
[   43.880376][  T319]  ? register_lock_class+0x3f/0x800
[   43.880531][  T319]  ? srso_alias_return_thunk+0x5/0xfbef5
[   43.880684][  T319]  ? __pfx___dev_queue_xmit+0x10/0x10
[   43.880834][  T319]  ? srso_alias_return_thunk+0x5/0xfbef5
[   43.880977][  T319]  ? __lock_acquire+0x819/0x1df0
[   43.881124][  T319]  ? srso_alias_return_thunk+0x5/0xfbef5
[   43.881275][  T319]  ? srso_alias_return_thunk+0x5/0xfbef5
[   43.881418][  T319]  ? __asan_memcpy+0x3c/0x60
[   43.881563][  T319]  ? srso_alias_return_thunk+0x5/0xfbef5
[   43.881708][  T319]  ? eth_header+0x165/0x1a0
[   43.881853][  T319]  ? lockdep_hardirqs_on_prepare+0xdb/0x1a0
[   43.882031][  T319]  ? srso_alias_return_thunk+0x5/0xfbef5
[   43.882174][  T319]  ? neigh_resolve_output+0x3cc/0x7e0
[   43.882325][  T319]  ? srso_alias_return_thunk+0x5/0xfbef5
[   43.882471][  T319]  ip_finish_output2+0x6b6/0x1e10

Fix this by calling qdisc_reset for CBS' child qdisc.
Sashiko caught an issue which could result in a null ptr deref if
qdisc_create_dflt() is invoked on an unitialised cbs qdisc which is exposed
by this patch. We add an early return if the qdisc is null to address this.
This is a similar approach used by two other fixes[1][2].

The proper fix for this specific issue elucidated by sashiko is to remove
the call to qdisc_reset when qdisc_create_dflt fails. Since the dflt qdisc
isn't attached anywhere yet at that point, calling the reset callback doesn't
make much sense (and as stated has been a source of two other bugs).
We plan on  submitting this fix in a later patch.
[1] https://lore.kernel.org/netdev/20221018063201.306474-2-shaozhengchao@huawei.com/
[2] https://lore.kernel.org/netdev/20221018063201.306474-4-shaozhengchao@huawei.com/

Fixes: 585d763af0 ("net/sched: Introduce Credit Based Shaper (CBS) qdisc")
Reported-by: Junyoung Jang <graypanda.inzag@gmail.com>
Tested-by: Junyoung Jang <graypanda.inzag@gmail.com>
Tested-by: Victor Nogueira <victor@mojatatu.com>
Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-13 17:53:39 -07:00
..
Kconfig sched: Add enqueue/dequeue of dualpi2 qdisc 2025-07-23 17:52:07 -07:00
Makefile sched: Add enqueue/dequeue of dualpi2 qdisc 2025-07-23 17:52:07 -07:00
act_api.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
act_bpf.c bpf: Add bpf_prog_run_data_pointers() 2025-11-14 08:56:49 -08:00
act_connmark.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
act_csum.c net: sched: act_csum: validate nested VLAN headers 2026-04-03 14:34:56 -07:00
act_ct.c net/sched: act_ct: Only release RCU read lock after ct_ft 2026-04-12 09:26:15 -07:00
act_ctinfo.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
act_gact.c
act_gate.c net/sched: act_gate: snapshot parameters with RCU on replace 2026-02-27 16:10:36 -08:00
act_ife.c net/sched: act_ife: Fix metalist update behavior 2026-03-05 07:54:08 -08:00
act_meta_mark.c
act_meta_skbprio.c
act_meta_skbtcindex.c
act_mirred.c net/sched: act_mirred: fix wrong device for mac_header_xmit check in tcf_blockcast_redir 2026-04-16 11:16:32 +02:00
act_mpls.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
act_nat.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
act_pedit.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
act_police.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
act_sample.c net: sched: act_sample: add action cookie to sample 2024-07-05 17:45:47 -07:00
act_simple.c net/sched: Remove redundant memset(0) call in reset_policy() 2025-08-12 17:13:29 -07:00
act_skbedit.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
act_skbmod.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
act_tunnel_key.c net_sched: add back BH safety to tcf_lock 2025-09-02 15:51:45 -07:00
act_vlan.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
bpf_qdisc.c bpf: net_sched: Use the correct destructor kfunc type 2026-01-12 18:53:57 -08:00
cls_api.c net: sched: cls_api: fix tc_chain_fill_node to initialize tcm_info to zero to prevent an info-leak 2026-03-30 17:56:40 -07:00
cls_basic.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cls_bpf.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cls_cgroup.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cls_flow.c net/sched: cls_flow: fix NULL pointer dereference on shared blocks 2026-04-02 15:08:42 +02:00
cls_flower.c net/sched: cls_flower: revert unintended changes 2026-04-30 13:47:01 +02:00
cls_fw.c net/sched: cls_fw: fix NULL dereference of "old" filters before change() 2026-04-12 08:49:13 -07:00
cls_matchall.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cls_route.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cls_u32.c net: sched: cls_u32: Avoid memcpy() false-positive warning in u32_init_knode() 2026-03-10 19:39:35 -07:00
em_canid.c net/sched: em_canid: fix uninit-value in em_canid_match 2025-11-26 16:28:10 +01:00
em_cmp.c net: sched: fix TCF_LAYER_TRANSPORT handling in tcf_get_base_ptr() 2025-11-24 18:53:14 -08:00
em_ipset.c
em_ipt.c
em_meta.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
em_nbyte.c net: sched: fix TCF_LAYER_TRANSPORT handling in tcf_get_base_ptr() 2025-11-24 18:53:14 -08:00
em_text.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
em_u32.c
ematch.c
sch_api.c net/sched: refine indirect call mitigation in tc_wrapper.h 2026-03-09 19:31:41 -07:00
sch_blackhole.c
sch_cake.c net/sched: sch_cake: annotate data-races in cake_dump_class_stats (II) 2026-05-02 16:59:09 -07:00
sch_cbs.c net/sched: sch_cbs: Call qdisc_reset for child qdisc 2026-05-13 17:53:39 -07:00
sch_choke.c net/sched: sch_choke: annotate data-races in choke_dump_stats() 2026-04-27 17:41:08 -07:00
sch_codel.c codel: annotate data-races in codel_dump_stats() 2026-04-08 19:18:52 -07:00
sch_drr.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
sch_dualpi2.c net/sched: dualpi2: initialize timer earlier in dualpi2_init() 2026-05-11 18:03:16 -07:00
sch_etf.c net_sched: sch_tfs: implement lockless etf_dump() 2024-04-19 11:34:07 +01:00
sch_ets.c net/sched: ets: fix divide by zero in the offload path 2026-02-26 18:28:47 -08:00
sch_fifo.c pfifo_tail_enqueue: Drop new packet when sch->limit == 0 2025-02-05 18:13:58 -08:00
sch_fq.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2026-03-05 12:11:05 -08:00
sch_fq_codel.c net/sched: sch_fq_codel: annotate data-races from fq_codel_dump_class_stats() 2026-05-05 18:01:28 -07:00
sch_fq_pie.c net/sched: sch_fq_pie: annotate data-races in fq_pie_dump_stats() 2026-04-27 17:41:52 -07:00
sch_frag.c net: convert remaining ipv6_stub users to direct function calls 2026-03-29 11:21:23 -07:00
sch_generic.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2026-03-19 14:16:00 -07:00
sch_gred.c net: sched: introduce qdisc-specific drop reason tracing 2026-02-28 15:31:34 -08:00
sch_hfsc.c net/sched: sch_hfsc: fix divide-by-zero in rtsc_min() 2026-03-27 20:41:11 -07:00
sch_hhf.c net_sched: sch_hhf: annotate data-races in hhf_dump_stats() 2026-04-22 21:12:40 -07:00
sch_htb.c net/sched: do not reset queues in graft operations 2026-03-09 18:55:55 -07:00
sch_ingress.c clsact: Fix use-after-free in init/destroy rollback asymmetry 2026-03-17 12:09:16 +01:00
sch_mq.c net/sched: do not reset queues in graft operations 2026-03-09 18:55:55 -07:00
sch_mqprio.c net/sched: do not reset queues in graft operations 2026-03-09 18:55:55 -07:00
sch_mqprio_lib.c
sch_mqprio_lib.h
sch_multiq.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
sch_netem.c net/sched: netem: check for negative latency and jitter 2026-04-27 17:30:28 -07:00
sch_pie.c net/sched: sch_pie: annotate more data-races in pie_dump_stats() 2026-05-01 17:54:57 -07:00
sch_plug.c
sch_prio.c net_sched: prio: fix a race in prio_tune() 2025-06-12 08:05:49 -07:00
sch_qfq.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
sch_red.c net/sched: sch_red: Replace direct dequeue call with peek and qdisc_dequeue_peeked 2026-05-02 10:20:55 -07:00
sch_sfb.c net/sched: sch_sfb: Replace direct dequeue call with peek and qdisc_dequeue_peeked 2026-05-02 10:20:56 -07:00
sch_sfq.c net/sched: sch_sfq: annotate data-races from sfq_dump_class_stats() 2026-05-06 17:46:05 -07:00
sch_skbprio.c net_sched: skbprio: Remove overly strict queue assertions 2025-04-02 16:03:32 -07:00
sch_taprio.c net/sched: taprio: fix NULL pointer dereference in class dump 2026-04-27 18:41:36 -07:00
sch_tbf.c net_sched: use qdisc_skb_cb(skb)->pkt_segs in bstats_update() 2025-11-25 16:10:32 +01:00
sch_teql.c net/sched: teql: Fix double-free in teql_master_xmit 2026-03-16 19:40:32 -07:00