From c96af7d8a421e31ec0e0a0ae5582254dfa84cbd2 Mon Sep 17 00:00:00 2001 From: Pedro Tammela Date: Sat, 15 Feb 2025 22:52:07 +0800 Subject: [PATCH] net/sched: stop qdisc_tree_reduce_backlog on TC_H_ROOT stable inclusion from stable-v5.10.229 commit ce691c814bc7a3c30c220ffb5b7422715458fd9b category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IB5KR7 CVE: CVE-2024-53057 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=ce691c814bc7a3c30c220ffb5b7422715458fd9b -------------------------------- [ Upstream commit 2e95c4384438adeaa772caa560244b1a2efef816 ] In qdisc_tree_reduce_backlog, Qdiscs with major handle ffff: are assumed to be either root or ingress. This assumption is bogus since it's valid to create egress qdiscs with major handle ffff: Budimir Markovic found that for qdiscs like DRR that maintain an active class list, it will cause a UAF with a dangling class pointer. In 066a3b5b2346, the concern was to avoid iterating over the ingress qdisc since its parent is itself. The proper fix is to stop when parent TC_H_ROOT is reached because the only way to retrieve ingress is when a hierarchy which does not contain a ffff: major handle call into qdisc_lookup with TC_H_MAJ(TC_H_ROOT). In the scenario where major ffff: is an egress qdisc in any of the tree levels, the updates will also propagate to TC_H_ROOT, which then the iteration must stop. Fixes: 066a3b5b2346 ("[NET_SCHED] sch_api: fix qdisc_tree_decrease_qlen() loop") Reported-by: Budimir Markovic Suggested-by: Jamal Hadi Salim Tested-by: Victor Nogueira Signed-off-by: Pedro Tammela Signed-off-by: Jamal Hadi Salim net/sched/sch_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Reviewed-by: Simon Horman Link: https://patch.msgid.link/20241024165547.418570-1-jhs@mojatatu.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin Signed-off-by: Dong Chenchen --- net/sched/sch_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index efd109652f22..0b809dfb0e43 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -781,7 +781,7 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, int n, int len) drops = max_t(int, n, 0); rcu_read_lock(); while ((parentid = sch->parent)) { - if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS)) + if (parentid == TC_H_ROOT) break; if (sch->flags & TCQ_F_NOPARENT) -- Gitee