Replace the hulk patch with the lts patch, thanks!
Gaosheng Cui (1): Revert "cgroup: Stop task iteration when rebinding subsystem"
Xiu Jianfeng (1): cgroup: Do not corrupt task iteration when rebinding subsystem
include/linux/cgroup.h | 1 - kernel/cgroup/cgroup.c | 50 ++++++++++++++---------------------------- 2 files changed, 16 insertions(+), 35 deletions(-)
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7AZ85
--------------------------------
This reverts commit e52586f4d49c0b6e934e00e8bfd9c1701c549966.
Signed-off-by: Gaosheng Cui cuigaosheng1@huawei.com --- include/linux/cgroup.h | 1 - kernel/cgroup/cgroup.c | 34 +--------------------------------- 2 files changed, 1 insertion(+), 34 deletions(-)
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 0dcf260a4c1c..a60e9966b32d 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -47,7 +47,6 @@ struct kernel_clone_args;
/* internal flags */ #define CSS_TASK_ITER_SKIPPED (1U << 16) -#define CSS_TASK_ITER_STOPPED (1U << 17)
/* a css_task_iter should be treated as an opaque object */ struct css_task_iter { diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 37041478c39c..648b5ede851c 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -215,8 +215,6 @@ static int cgroup_apply_control(struct cgroup *cgrp); static void cgroup_finalize_control(struct cgroup *cgrp, int ret); static void css_task_iter_skip(struct css_task_iter *it, struct task_struct *task); -static void css_task_iter_stop(struct css_task_iter *it, - struct cgroup_subsys *ss); static int cgroup_destroy_locked(struct cgroup *cgrp); static struct cgroup_subsys_state *css_create(struct cgroup *cgrp, struct cgroup_subsys *ss); @@ -857,19 +855,6 @@ static void css_set_skip_task_iters(struct css_set *cset, css_task_iter_skip(it, task); }
-/* - * @cset is moving to other list, it's not safe to continue the iteration, - * because the cset_head of css_task_iter which is from the old list can - * not be used as the stop condition of iteration. - */ -static void css_set_stop_iters(struct css_set *cset, struct cgroup_subsys *ss) -{ - struct css_task_iter *it, *pos; - - list_for_each_entry_safe(it, pos, &cset->task_iters, iters_node) - css_task_iter_stop(it, ss); -} - /** * css_set_move_task - move a task from one css_set to another * @task: task being moved @@ -1790,11 +1775,9 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask) css->cgroup = dcgrp;
spin_lock_irq(&css_set_lock); - hash_for_each(css_set_table, i, cset, hlist) { - css_set_stop_iters(cset, ss); + hash_for_each(css_set_table, i, cset, hlist) list_move_tail(&cset->e_cset_node[ss->id], &dcgrp->e_csets[ss->id]); - } spin_unlock_irq(&css_set_lock);
if (ss->css_rstat_flush) { @@ -4723,16 +4706,6 @@ static void css_task_iter_skip(struct css_task_iter *it, } }
-static void css_task_iter_stop(struct css_task_iter *it, - struct cgroup_subsys *ss) -{ - lockdep_assert_held(&css_set_lock); - - if (it->ss == ss) { - it->flags |= CSS_TASK_ITER_STOPPED; - } -} - static void css_task_iter_advance(struct css_task_iter *it) { struct task_struct *task; @@ -4836,11 +4809,6 @@ struct task_struct *css_task_iter_next(struct css_task_iter *it)
spin_lock_irq(&css_set_lock);
- if (it->flags & CSS_TASK_ITER_STOPPED) { - spin_unlock_irq(&css_set_lock); - return NULL; - } - /* @it may be half-advanced by skips, finish advancing */ if (it->flags & CSS_TASK_ITER_SKIPPED) css_task_iter_advance(it);
From: Xiu Jianfeng xiujianfeng@huawei.com
stable inclusion from stable-v5.10.186 commit 63608437a83ddabe497cfc163237e654eb563701 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7AZ85 CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit 6f363f5aa845561f7ea496d8b1175e3204470486 upstream.
We found a refcount UAF bug as follows:
refcount_t: addition on 0; use-after-free. WARNING: CPU: 1 PID: 342 at lib/refcount.c:25 refcount_warn_saturate+0xa0/0x148 Workqueue: events cpuset_hotplug_workfn Call trace: refcount_warn_saturate+0xa0/0x148 __refcount_add.constprop.0+0x5c/0x80 css_task_iter_advance_css_set+0xd8/0x210 css_task_iter_advance+0xa8/0x120 css_task_iter_next+0x94/0x158 update_tasks_root_domain+0x58/0x98 rebuild_root_domains+0xa0/0x1b0 rebuild_sched_domains_locked+0x144/0x188 cpuset_hotplug_workfn+0x138/0x5a0 process_one_work+0x1e8/0x448 worker_thread+0x228/0x3e0 kthread+0xe0/0xf0 ret_from_fork+0x10/0x20
then a kernel panic will be triggered as below:
Unable to handle kernel paging request at virtual address 00000000c0000010 Call trace: cgroup_apply_control_disable+0xa4/0x16c rebind_subsystems+0x224/0x590 cgroup_destroy_root+0x64/0x2e0 css_free_rwork_fn+0x198/0x2a0 process_one_work+0x1d4/0x4bc worker_thread+0x158/0x410 kthread+0x108/0x13c ret_from_fork+0x10/0x18
The race that cause this bug can be shown as below:
(hotplug cpu) | (umount cpuset) mutex_lock(&cpuset_mutex) | mutex_lock(&cgroup_mutex) cpuset_hotplug_workfn | rebuild_root_domains | rebind_subsystems update_tasks_root_domain | spin_lock_irq(&css_set_lock) css_task_iter_start | list_move_tail(&cset->e_cset_node[ss->id] while(css_task_iter_next) | &dcgrp->e_csets[ss->id]); css_task_iter_end | spin_unlock_irq(&css_set_lock) mutex_unlock(&cpuset_mutex) | mutex_unlock(&cgroup_mutex)
Inside css_task_iter_start/next/end, css_set_lock is hold and then released, so when iterating task(left side), the css_set may be moved to another list(right side), then it->cset_head points to the old list head and it->cset_pos->next points to the head node of new list, which can't be used as struct css_set.
To fix this issue, switch from all css_sets to only scgrp's css_sets to patch in-flight iterators to preserve correct iteration, and then update it->cset_head as well.
Reported-by: Gaosheng Cui cuigaosheng1@huawei.com Link: https://www.spinics.net/lists/cgroups/msg37935.html Suggested-by: Michal Koutný mkoutny@suse.com Link: https://lore.kernel.org/all/20230526114139.70274-1-xiujianfeng@huaweicloud.c... Signed-off-by: Xiu Jianfeng xiujianfeng@huawei.com Fixes: 2d8f243a5e6e ("cgroup: implement cgroup->e_csets[]") Cc: stable@vger.kernel.org # v3.16+ Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
Conflicts: kernel/cgroup/cgroup.c
Signed-off-by: Gaosheng Cui cuigaosheng1@huawei.com --- kernel/cgroup/cgroup.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 648b5ede851c..d0a4a1c4c38d 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -1713,7 +1713,7 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask) { struct cgroup *dcgrp = &dst_root->cgrp; struct cgroup_subsys *ss; - int ssid, i, ret; + int ssid, ret; u16 dfl_disable_ss_mask = 0;
lockdep_assert_held(&cgroup_mutex); @@ -1757,7 +1757,8 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask) struct cgroup_root *src_root = ss->root; struct cgroup *scgrp = &src_root->cgrp; struct cgroup_subsys_state *css = cgroup_css(scgrp, ss); - struct css_set *cset; + struct css_set *cset, *cset_pos; + struct css_task_iter *it;
WARN_ON(!css || cgroup_css(dcgrp, ss));
@@ -1775,9 +1776,22 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask) css->cgroup = dcgrp;
spin_lock_irq(&css_set_lock); - hash_for_each(css_set_table, i, cset, hlist) + WARN_ON(!list_empty(&dcgrp->e_csets[ss->id])); + list_for_each_entry_safe(cset, cset_pos, &scgrp->e_csets[ss->id], + e_cset_node[ss->id]) { list_move_tail(&cset->e_cset_node[ss->id], &dcgrp->e_csets[ss->id]); + /* + * all css_sets of scgrp together in same order to dcgrp, + * patch in-flight iterators to preserve correct iteration. + * since the iterator is always advanced right away and + * finished when it->cset_pos meets it->cset_head, so only + * update it->cset_head is enough here. + */ + list_for_each_entry(it, &cset->task_iters, iters_node) + if (it->cset_head == &scgrp->e_csets[ss->id]) + it->cset_head = &dcgrp->e_csets[ss->id]; + } spin_unlock_irq(&css_set_lock);
if (ss->css_rstat_flush) {
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/1408 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/K...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/1408 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/K...