hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IDB5TR ----------------------------------------- css_free() is executed asynchronously via css_free_work_fn() when the CSS reference count reaches zero. Performing list_del() within this asynchronous context can lead to list corruption if other operations concurrently access the same list. The issue arises because: 1. css_free() runs in workqueue context, potentially delayed 2. Other code paths may assume the CSS is already removed from lists 3. Concurrent list operations during this window can corrupt list pointers Solution: Move the list_del() operation from css_free() to css_offline(), which: - Runs synchronously during CSS teardown - Ensures timely removal from all lists - Maintains list integrity throughout the destruction process This guarantees that once css_offline() completes, the CSS is no longer present in any shared lists, preventing use-after-free races. Fixes: 34a49359681b ("xsched: prevent NULL deref by refcounting css and tracking offline state") Signed-off-by: Liu Kai <liukai284@huawei.com> --- kernel/xsched/cgroup.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/kernel/xsched/cgroup.c b/kernel/xsched/cgroup.c index 8f3e2d9e9e12..e50556a82cea 100644 --- a/kernel/xsched/cgroup.c +++ b/kernel/xsched/cgroup.c @@ -196,7 +196,7 @@ static int xcu_cg_init(struct xsched_group *xcg, return xcu_cfs_cg_init(xcg, parent_xg); default: XSCHED_INFO("xcu_cgroup: init RT group css=0x%lx\n", - (uintptr_t)&xcg->css); + (uintptr_t)&xcg->css); break; } @@ -243,20 +243,6 @@ static void xcu_css_free(struct cgroup_subsys_state *css) { struct xsched_group *xcg = xcu_cg_from_css(css); - if (!xsched_group_is_root(xcg)) { - switch (xcg->sched_class) { - case XSCHED_TYPE_CFS: - xcu_cfs_cg_deinit(xcg); - break; - default: - XSCHED_INFO("xcu_cgroup: deinit RT group css=0x%lx\n", - (uintptr_t)&xcg->css); - break; - } - } - - list_del(&xcg->group_node); - kmem_cache_free(xsched_group_cache, xcg); } @@ -318,6 +304,20 @@ static void xcu_css_offline(struct cgroup_subsys_state *css) hrtimer_cancel(&xcg->quota_timeout); cancel_work_sync(&xcg->refill_work); cancel_work_sync(&xcg->file_show_work); + + if (!xsched_group_is_root(xcg)) { + switch (xcg->sched_class) { + case XSCHED_TYPE_CFS: + xcu_cfs_cg_deinit(xcg); + break; + default: + XSCHED_INFO("xcu_cgroup: deinit RT group css=0x%lx\n", + (uintptr_t)&xcg->css); + break; + } + } + + list_del(&xcg->group_node); } static void xsched_group_xse_attach(struct xsched_group *xg, -- 2.34.1