[PATCH 4/4] mm/mempolicy: kernel_migrate_pages: fix race between security checks and suid exec
From: Oleg Nesterov
Date: Sun May 24 2026 - 12:59:11 EST
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 <oleg@xxxxxxxxxx>
---
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