Skip to contentSkip to conversation

FAILED: patch "[PATCH] net/sched: reject overly deep qdisc hierarchies" failed to apply to 5.10-stable tree

PATCH New [email protected] 2 participants 2 messages Aug 17 – Aug 21

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x dedd34b0f2310e28c5f6d4875cfbf4b7ed821c01
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026081713-handiwork-idealness-deb8@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'

Possible dependencies:

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From dedd34b0f2310e28c5f6d4875cfbf4b7ed821c01 Mon Sep 17 00:00:00 2001
From: Zijie Huang <[email protected]>
Date: Sat, 1 Aug 2026 21:42:33 +0800
Subject: [PATCH] net/sched: reject overly deep qdisc hierarchies

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.

include/net/sch_generic.h +1 -0
index 45a1e8c78222..cbc248776511 100644
@@ -99,6 +99,7 @@ struct Qdisc {
 	struct hlist_node       hash;
 	u32			handle;
 	u32			parent;
+	int			depth;
 
 	struct netdev_queue	*dev_queue;
 
net/sched/sch_api.c +9 -0
index 668bcd60d183..65b35528d125 100644
@@ -1114,6 +1114,9 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
 		unsigned int i, num_q, ingress;
 		struct netdev_queue *dev_queue;
 
+		if (new)
+			new->depth = 0;
+
 		ingress = 0;
 		num_q = dev->num_tx_queues;
 		if ((q && q->flags & TCQ_F_INGRESS) ||
@@ -1211,9 +1214,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, extack);
 	}
 	return 0;
maintainer
#1 lore raw

PATCH 1/1 net/sched: reject overly deep qdisc hierarchies

From: Zijie Huang <[email protected]>

[ Upstream commit dedd34b0f2310e28c5f6d4875cfbf4b7ed821c01 ]

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.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
Assisted-by Codex:gpt-5.4
[ Dropped the `extack` argument from the `notify_and_destroy()` context line to match 5.15's 6-parameter version. ]
---
 include/net/sch_generic.h | 1 +
 net/sched/sch_api.c       | 9 +++++++++
 2 files changed, 10 insertions(+)
include/net/sch_generic.h +1 -0
index a4c670ad8c4ac..b46a70602da44 100644
@@ -86,6 +86,7 @@ struct Qdisc {
 	struct hlist_node       hash;
 	u32			handle;
 	u32			parent;
+	int			depth;
 
 	struct netdev_queue	*dev_queue;
 
net/sched/sch_api.c +9 -0
index 932c98b5b347e..9c90b54e46300 100644
@@ -1031,6 +1031,9 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
 		unsigned int i, num_q, ingress;
 		struct netdev_queue *dev_queue;
 
+		if (new)
+			new->depth = 0;
+
 		ingress = 0;
 		num_q = dev->num_tx_queues;
 		if ((q && q->flags & TCQ_F_INGRESS) ||
@@ -1110,9 +1113,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;
Signature · 1 line
2.53.0