From: Zijie Huang When creating a new qdisc under an existing classful qdisc, the current code does not check the depth of the parent hierarchy before grafting the new qdisc. This allows users to grow a qdisc hierarchy one level at a time past the intended depth limit. Reject the operation before creating the new qdisc when the parent hierarchy is already too deep. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reported-by: Vega Assisted-by: Codex:gpt-5.4 Signed-off-by: Zijie Huang Signed-off-by: Ren Wei --- net/sched/sch_api.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 668bcd60d183..09d57ad76b89 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -1467,6 +1467,24 @@ check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w) return 0; } +static int qdisc_parent_depth(struct net_device *dev, struct Qdisc *qdisc) +{ + int depth = 1; + + while (qdisc->parent != TC_H_ROOT) { + if (qdisc->flags & TCQ_F_NOPARENT) + break; + + qdisc = qdisc_lookup(dev, TC_H_MAJ(qdisc->parent)); + if (!qdisc) + break; + + depth++; + } + + return depth; +} + const struct nla_policy rtm_tca_policy[TCA_MAX + 1] = { [TCA_KIND] = { .type = NLA_STRING }, [TCA_RATE] = { .type = NLA_BINARY, @@ -1749,6 +1767,12 @@ static int __tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, return -ENOENT; } create_n_graft2: + if (p && !(p->flags & TCQ_F_MQROOT) && + qdisc_parent_depth(dev, p) > 7) { + NL_SET_ERR_MSG(extack, "Qdisc hierarchy is too deep"); + return -E2BIG; + } + if (clid == TC_H_INGRESS) { if (dev_ingress_queue(dev)) { q = qdisc_create(dev, dev_ingress_queue(dev), -- 2.47.2