From 0e6ca1640cec57004d702e5e7c3e59ba77541e2f Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Tue, 25 Sep 2018 14:29:03 +0530 Subject: [PATCH] sched/core: Fix use after free issue in is_sched_lib_based_app() is_sched_lib_based_app() function introduced by 'commit d43b69c4ad2a ("sched/core: fix userspace affining threads incorrectly")' traverses all the executable VMA regions of a task for which the affinity change is requested by the userspace. The mm->mmap_sem lock is acquired to lock the VMA regions, however the task mm itself can go away when the task is exited. The get_task_struct() does not prevent this from happening. Add protection by incrementing task's mm reference count. Change-Id: I39d835a8d7d53d9b9eca90baf73d3fcfad9d164b Signed-off-by: Pavankumar Kondeti --- kernel/sched/core.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 94e6c587539d..efdc2117f50e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -4917,6 +4917,7 @@ static inline bool is_sched_lib_based_app(pid_t pid) char path_buf[LIB_PATH_LENGTH]; bool found = false; struct task_struct *p; + struct mm_struct *mm; if (strnlen(sched_lib_name, LIB_PATH_LENGTH) == 0) return false; @@ -4933,11 +4934,12 @@ static inline bool is_sched_lib_based_app(pid_t pid) get_task_struct(p); rcu_read_unlock(); - if (!p->mm) + mm = get_task_mm(p); + if (!mm) goto put_task_struct; - down_read(&p->mm->mmap_sem); - for (vma = p->mm->mmap; vma ; vma = vma->vm_next) { + down_read(&mm->mmap_sem); + for (vma = mm->mmap; vma ; vma = vma->vm_next) { if (vma->vm_file && vma->vm_flags & VM_EXEC) { name = d_path(&vma->vm_file->f_path, path_buf, LIB_PATH_LENGTH); @@ -4953,7 +4955,8 @@ static inline bool is_sched_lib_based_app(pid_t pid) } release_sem: - up_read(&p->mm->mmap_sem); + up_read(&mm->mmap_sem); + mmput(mm); put_task_struct: put_task_struct(p); return found;