[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251205014855.736723-1-xmei5@asu.edu>
Date: Thu, 4 Dec 2025 18:48:55 -0700
From: Xiang Mei <xmei5@....edu>
To: security@...nel.org
Cc: netdev@...r.kernel.org,
jhs@...atatu.com,
xiyou.wangcong@...il.com,
jiri@...nulli.us,
Xiang Mei <xmei5@....edu>
Subject: [PATCH net] net/sched: sch_qfq: Fix NULL deref when deactivating
`qfq_class->leaf_qdisc->q.qlen > 0` does not imply that the class
itself is active.
Two qfq_class objects may point to the same leaf_qdisc. This happens
when:
1. one QFQ qdisc is attached to the dev as the root qdisc, and
2. another QFQ qdisc is temporarily referenced (e.g., via qdisc_get()
/ qdisc_put()) and is pending to be destroyed, as in function
tc_new_tfilter.
When packets are enqueued through the root QFQ qdisc, the shared
leaf_qdisc->q.qlen increases. At the same time, the second QFQ
qdisc triggers qdisc_put and qdisc_destroy: the qdisc enters
qfq_reset() with its own q->q.qlen == 0, but its class's leaf
qdisc->q.qlen > 0. Therefore, the qfq_reset would wrongly deactivate
an inactive aggregate and trigger a null-deref in qfq_deactivate_agg.
Fixes: 0545a3037773 ("pkt_sched: QFQ - quick fair queue scheduler")
Signed-off-by: Xiang Mei <xmei5@....edu>
---
net/sched/sch_qfq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index d920f57dc6d7..f4013b547438 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -1481,7 +1481,7 @@ static void qfq_reset_qdisc(struct Qdisc *sch)
for (i = 0; i < q->clhash.hashsize; i++) {
hlist_for_each_entry(cl, &q->clhash.hash[i], common.hnode) {
- if (cl->qdisc->q.qlen > 0)
+ if (cl_is_active(cl))
qfq_deactivate_class(q, cl);
qdisc_reset(cl->qdisc);
--
2.43.0
Powered by blists - more mailing lists