net/sched/cls_u32.c | 3 +++ 1 file changed, 3 insertions(+)
u32_walk() enumerates both struct tc_u_hnode and struct tc_u_knode
through the walker callback. u32_bind_class() unconditionally casts the
passed fh to tc_u_knode and accesses &n->res, so when fh is actually a
tc_u_hnode, which has no tcf_result member, this results in a
slab-out-of-bounds read of res->classid in tc_cls_bind_class().
The issue can be reproduced with the following commands:
tc qdisc add dev lo root handle 1: hfsc
tc class add dev lo parent 1: classid 1:1 hfsc sc rate 1000kbit
tc filter add dev lo parent 1:1 protocol ip prio 1 u32 match u32 0 0 flowid 1:1
tc class add dev lo parent 1: classid 1:2 hfsc sc rate 2000kbit
Fix this by skipping hash tables via the TC_U32_KEY(handle) check.
Fixes: 07d79fc7d94e ("net_sched: add reverse binding for tc class")
Signed-off-by: Zhang Changzhong <zhangchangzhong@huawei.com>
---
net/sched/cls_u32.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 34d25f7..90ad80b 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -1250,6 +1250,9 @@ static void u32_bind_class(void *fh, u32 classid, unsigned long cl, void *q,
{
struct tc_u_knode *n = fh;
+ if (TC_U32_KEY(n->handle) == 0)
+ return;
+
tc_cls_bind_class(classid, cl, q, &n->res, base);
}
--
2.9.5
On Fri, Aug 7, 2026 at 2:58 AM Zhang Changzhong
<zhangchangzhong@huawei.com> wrote:
>
> u32_walk() enumerates both struct tc_u_hnode and struct tc_u_knode
> through the walker callback. u32_bind_class() unconditionally casts the
> passed fh to tc_u_knode and accesses &n->res, so when fh is actually a
> tc_u_hnode, which has no tcf_result member, this results in a
> slab-out-of-bounds read of res->classid in tc_cls_bind_class().
>
> The issue can be reproduced with the following commands:
>
> tc qdisc add dev lo root handle 1: hfsc
> tc class add dev lo parent 1: classid 1:1 hfsc sc rate 1000kbit
> tc filter add dev lo parent 1:1 protocol ip prio 1 u32 match u32 0 0 flowid 1:1
> tc class add dev lo parent 1: classid 1:2 hfsc sc rate 2000kbit
>
> Fix this by skipping hash tables via the TC_U32_KEY(handle) check.
>
Reproduced.
The commit message would be better with what the sashikos prescribed:
example to describe the type-confusion impact accurately (wrong-field
read/write + spurious refcount, OOB read only under the tracker
config) rather than "slab-out-of-bounds read" or "OOB store".
Dont want to push for v2:
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
cheers,
jamal
> Fixes: 07d79fc7d94e ("net_sched: add reverse binding for tc class")
> Signed-off-by: Zhang Changzhong <zhangchangzhong@huawei.com>
> ---
> net/sched/cls_u32.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
> index 34d25f7..90ad80b 100644
> --- a/net/sched/cls_u32.c
> +++ b/net/sched/cls_u32.c
> @@ -1250,6 +1250,9 @@ static void u32_bind_class(void *fh, u32 classid, unsigned long cl, void *q,
> {
> struct tc_u_knode *n = fh;
>
> + if (TC_U32_KEY(n->handle) == 0)
> + return;
> +
> tc_cls_bind_class(classid, cl, q, &n->res, base);
> }
>
> --
> 2.9.5
>
© 2016 - 2026 Red Hat, Inc.