From: Cheng-Yang Chou Date: Mon, 23 Mar 2026 10:48:29 +0000 (+0800) Subject: sched_ext: Fix invalid kobj cast in scx_uevent() X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4624211bc633481523475d0586a47c0a31c91fa4;p=thirdparty%2Flinux.git sched_ext: Fix invalid kobj cast in scx_uevent() When scx_alloc_and_add_sched() creates the sub-scheduler kset, it sets sch->kobj as the parent. Because sch->kobj.kset points to scx_kset, registering this sub-kset triggers a KOBJ_ADD uevent. The uevent walk finds scx_kset and calls scx_uevent() with the sub-kset's kobject. scx_uevent() unconditionally uses container_of() to cast the incoming kobject to struct scx_sched, producing a wild pointer when the kobject belongs to the kset itself rather than a scheduler instance. Accessing sch->ops.name through this pointer causes a KASAN slab-out-of-bounds read: BUG: KASAN: slab-out-of-bounds in string+0x3b6/0x4c0 Read of size 1 at addr ffff888004d04348 by task scx_enable_help/748 Call Trace: string+0x3b6/0x4c0 vsnprintf+0x3ec/0x1550 add_uevent_var+0x160/0x3a0 scx_uevent+0x22/0x30 kobject_uevent_env+0x5dc/0x1730 kset_register+0x192/0x280 scx_alloc_and_add_sched+0x130d/0x1c60 ... Fix this by checking the kobject's ktype against scx_ktype before performing the cast, and returning 0 for non-matching kobjects. Tested with vng and scx_qmap without triggering any KASAN errors. Fixes: ebeca1f930ea ("sched_ext: Introduce cgroup sub-sched support") Signed-off-by: Cheng-Yang Chou Signed-off-by: Tejun Heo --- diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index 72a07eb050a38..2472231ec5566 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -4842,7 +4842,17 @@ static const struct kobj_type scx_ktype = { static int scx_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) { - const struct scx_sched *sch = container_of(kobj, struct scx_sched, kobj); + const struct scx_sched *sch; + + /* + * scx_uevent() can be reached by both scx_sched kobjects (scx_ktype) + * and sub-scheduler kset kobjects (kset_ktype) through the parent + * chain walk. Filter out the latter to avoid invalid casts. + */ + if (kobj->ktype != &scx_ktype) + return 0; + + sch = container_of(kobj, struct scx_sched, kobj); return add_uevent_var(env, "SCXOPS=%s", sch->ops.name); }