[SRU][J/N/Q][PATCH 1/1] net/sched: Enforce that teql can only be used as root qdisc
Tim Whisonant
tim.whisonant at canonical.com
Mon Feb 9 20:45:43 UTC 2026
From: Jamal Hadi Salim <jhs at mojatatu.com>
Design intent of teql is that it is only supposed to be used as root qdisc.
We need to check for that constraint.
Although not important, I will describe the scenario that unearthed this
issue for the curious.
GangMin Kim <km.kim1503 at gmail.com> managed to concot a scenario as follows:
ROOT qdisc 1:0 (QFQ)
├── class 1:1 (weight=15, lmax=16384) netem with delay 6.4s
└── class 1:2 (weight=1, lmax=1514) teql
GangMin sends a packet which is enqueued to 1:1 (netem).
Any invocation of dequeue by QFQ from this class will not return a packet
until after 6.4s. In the meantime, a second packet is sent and it lands on
1:2. teql's enqueue will return success and this will activate class 1:2.
Main issue is that teql only updates the parent visible qlen (sch->q.qlen)
at dequeue. Since QFQ will only call dequeue if peek succeeds (and teql's
peek always returns NULL), dequeue will never be called and thus the qlen
will remain as 0. With that in mind, when GangMin updates 1:2's lmax value,
the qfq_change_class calls qfq_deact_rm_from_agg. Since the child qdisc's
qlen was not incremented, qfq fails to deactivate the class, but still
frees its pointers from the aggregate. So when the first packet is
rescheduled after 6.4 seconds (netem's delay), a dangling pointer is
accessed causing GangMin's causing a UAF.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: GangMin Kim <km.kim1503 at gmail.com>
Tested-by: Victor Nogueira <victor at mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs at mojatatu.com>
Link: https://patch.msgid.link/20260114160243.913069-2-jhs@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba at kernel.org>
(cherry picked from commit 50da4b9d07a7a463e2cfb738f3ad4cff6b2c9c3b)
CVE-2026-23074
Signed-off-by: Tim Whisonant <tim.whisonant at canonical.com>
---
net/sched/sch_teql.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 8badec6d82a24..6e4bdaa876ed6 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -178,6 +178,11 @@ static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt,
if (m->dev == dev)
return -ELOOP;
+ if (sch->parent != TC_H_ROOT) {
+ NL_SET_ERR_MSG_MOD(extack, "teql can only be used as root");
+ return -EOPNOTSUPP;
+ }
+
q->m = m;
skb_queue_head_init(&q->q);
--
2.43.0
More information about the kernel-team
mailing list