On Sat, Aug 1, 2026 at 9:42 AM Ren Wei <[email protected]> wrote: > > From: Zijie Huang <[email protected]> > > 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") > Cc: [email protected] > Reported-by: Vega <[email protected]> > Assisted-by: Codex:gpt-5.4 > Signed-off-by: Zijie Huang <[email protected]> > Signed-off-by: Ren Wei <[email protected]>
This is the same patch i sent you except you changed the failure path to send EBIG instead of ELOOP. Is there a reason? And your feedback message is not as informative like what i had. NL_SET_ERR_MSG(extack, "Qdisc hierarchy too deep (max 7)"); This way the user doesnt have to dig to find what the limit is. Note: Your AI did not assist in this patch rather, I spent about 30 minutes looking closely using human knowledge. I am not looking for credit but for your education going forward: if someone invests their time reviewing your AI generated patches and suggests a different path that you adopt, please add a suggested-by tag crediting them. Or don't bother sending any patches, just report the problem and provide the Poc, I could have come up with that patch in about the same time investment. I am going to ack the series unless someone complains about EBIG vs ELOOP in which case please fix the msg.. cheers, jamal > changes in v2: > - Store the qdisc hierarchy depth in struct Qdisc and update it from > qdisc_graft(), instead of walking the parent chain. > - Move the depth check to qdisc_graft() so it is applied at the actual > attach point. > - Add tdc tests for the maximum allowed depth and rejection above it. > - v1 Link: > https://lore.kernel.org/all/[email protected]/ > > > 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 45a1e8c78222..cbc248776511 100644 > --- a/include/net/sch_generic.h > +++ b/include/net/sch_generic.h > @@ -99,6 +99,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 668bcd60d183..65b35528d125 100644 > --- a/net/sched/sch_api.c > +++ b/net/sched/sch_api.c > @@ -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; > -- > 2.47.2 >

