From: Zhang Xiaoxu zhangxiaoxu5@huawei.com
hulk inclusion category: bugfix bugzilla: NA CVE: NA
---------------------------
When fix CVE-2018-12207, the kvm_vm_worker_thread will attach all cgroup subsystem. But the files cgroup doesn't support kernel thread.
Because the init_files doesn't init the files cgroup, when kernel thread 'kvm_vm_worker_thread' attach the files cgroup, the files_cgroup get from 'init_files' is an error pointer. It lead the kernel panic as below: [ 724.842302] page_counter_uncharge+0x1d/0x30 [ 724.842431] files_cgroup_attach+0x7c/0x130 [ 724.842564] ? css_set_move_task+0x12e/0x230 [ 724.842694] cgroup_migrate_execute+0x2f9/0x3b0 [ 724.842833] cgroup_attach_task+0x156/0x200 [ 724.843010] ? kvm_mmu_pte_write+0x490/0x490 [kvm] [ 724.843153] cgroup_attach_task_all+0x81/0xd0 [ 724.843289] ? __schedule+0x294/0x910 [ 724.843419] kvm_vm_worker_thread+0x4a/0xc0 [kvm] [ 724.843579] ? kvm_exit+0x80/0x80 [kvm] [ 724.843690] kthread+0x112/0x130 [ 724.843792] ?kthread_create_worker_on_cpu+0x70/0x70 [ 724.843948] ret_from_fork+0x35/0x40
So, we add some check, if the task is kernel thread (files is 'init_files'), we doesn't do the more operation about the files cgroup.
Fixes: baa10bc24e1e ("kvm: Add helper function for creating VM ...") Signed-off-by: Zhang Xiaoxu zhangxiaoxu5@huawei.com Reviewed-by: Jason Yan yanaijie@huawei.com Reviewed-by: Hou Tao houtao1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/filescontrol.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/fs/filescontrol.c b/fs/filescontrol.c index fbaeacb..5ec5096 100644 --- a/fs/filescontrol.c +++ b/fs/filescontrol.c @@ -171,7 +171,7 @@ static void files_cgroup_attach(struct cgroup_taskset *tset)
task_lock(task); files = task->files; - if (!files) { + if (!files || files == &init_files) { task_unlock(task); return; } @@ -311,6 +311,9 @@ void files_cgroup_assign(struct files_struct *files) { struct cgroup_subsys_state *css;
+ if (files == &init_files) + return; + css = task_get_css(current, files_cgrp_id); files->files_cgroup = container_of(css, struct files_cgroup, css); } @@ -320,6 +323,9 @@ void files_cgroup_remove(struct files_struct *files) struct task_struct *tsk = current; struct files_cgroup *fcg;
+ if (files == &init_files) + return; + task_lock(tsk); spin_lock(&files->file_lock); fcg = files_cgroup_from_files(files);