The target task can execute a setuid binary between ptrace_may_access() and get_task_mm(). Protect this critical section with exec_update_lock. Sadly, we don't have DEFINE_LOCK_GUARD_1_COND(rwsem_read, _kill) yet. Signed-off-by: Oleg Nesterov --- mm/mempolicy.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index c09ff9f9aa96..cbb45a876a93 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1902,24 +1902,31 @@ static int kernel_migrate_pages(pid_t pid, unsigned long maxnode, goto out_put; } + err = down_read_killable(&task->signal->exec_update_lock); + if (err) + goto out_put; /* * Check if this process has the right to modify the specified process. * Use the regular "ptrace_may_access()" checks. */ if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) { err = -EPERM; - goto out_put; + goto unlock; } err = security_task_movememory(task); if (err) - goto out_put; + goto unlock; mm = get_task_mm(task); if (!mm) { err = -EINVAL; - goto out_put; + goto unlock; } +unlock: + up_read(&task->signal->exec_update_lock); + if (err) + goto out_put; err = do_migrate_pages(mm, old, new, capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE); -- 2.52.0