@@ -1994,12 +1994,23 @@ static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data
if (prctl_map.exe_fd != (u32)-1) {
/*
- * Make sure the caller has the rights to
- * change /proc/pid/exe link: only local sys admin should
- * be allowed to.
+ * The current process is authorized to change its
+ * /proc/self/exe link via two policies:
+ * 1) The current user can do checkpoint/restore
+ * In other words is CAP_SYS_ADMIN or
+ * CAP_CHECKPOINT_RESTORE capable.
+ * 2) The current user can use ptrace.
+ *
+ * With access to ptrace facilities, a process can do the
+ * following: fork a child, execve() the target executable,
+ * and have the child use ptrace() to replace the memory
+ * content of the current process. This technique makes it
+ * possible to masquerade an arbitrary program as the target
+ * executable, even if it is setuid.
*/
- if (!ns_capable(current_user_ns(), CAP_SYS_ADMIN))
- return -EINVAL;
+ if (!(checkpoint_restore_ns_capable(current_user_ns()) ||
+ security_ptrace_access_check(current, PTRACE_MODE_ATTACH_REALCREDS)))
+ return -EPERM;
error = prctl_set_mm_exe_file(mm, prctl_map.exe_fd);
if (error)