From bf710a3355977cc54156039da639566404a04e82 Mon Sep 17 00:00:00 2001 From: Zijie Huang Date: Sat, 1 Aug 2026 21:42:33 +0800 Subject: [PATCH] net/sched: reject overly deep qdisc hierarchies ANBZ: #44445 commit dedd34b0f2310e28c5f6d4875cfbf4b7ed821c01 upstream. Deep qdisc hierarchies can lead to excessive recursion in qdisc tree walkers and exhaust the kernel stack. The existing loop check does not cover the create-and-graft path, so a hierarchy can still be extended by creating a new child qdisc below an already deep parent. Store the hierarchy depth in struct Qdisc and update it when qdiscs are grafted. Reject new child qdiscs once the parent is already at the maximum allowed depth. [backport-note] PatchPilot-Conflict-Type: context_drift Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Suggested-by: Jamal Hadi Salim Reported-by: Vega Assisted-by: Codex:gpt-5.4 Signed-off-by: Zijie Huang Signed-off-by: Ren Wei Reviewed-by: Victor Nogueira Link: https://patch.msgid.link/1e9ab39597423fd5d13cfaaf52279b8ee3d9fc3c.1785434373.git.milkory@outlook.com Acked-by: Jamal Hadi Salim Signed-off-by: Paolo Abeni Fixes: CVE-2026-74663 Assisted-by: PatchPilot Signed-off-by: D. Wythe --- include/net/sch_generic.h | 1 + net/sched/sch_api.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index e357c7a0a77b..3f45225fe91c 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -87,6 +87,7 @@ struct Qdisc { struct hlist_node hash; u32 handle; u32 parent; + int depth; struct netdev_queue *dev_queue; diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index fc43ea55f0f3..e1575bc906bd 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -1044,6 +1044,9 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, if (parent == NULL) { unsigned int i, num_q, ingress; + if (new) + new->depth = 0; + ingress = 0; num_q = dev->num_tx_queues; if ((q && q->flags & TCQ_F_INGRESS) || @@ -1124,9 +1127,15 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, NL_SET_ERR_MSG(extack, "STAB not supported on a non root"); return -EINVAL; } + if (new && parent->depth >= 7) { + NL_SET_ERR_MSG(extack, "Qdisc hierarchy is too deep"); + return -E2BIG; + } err = cops->graft(parent, cl, new, &old, extack); if (err) return err; + if (new) + new->depth = parent->depth + 1; notify_and_destroy(net, skb, n, classid, old, new); } return 0; -- Gitee