Message ID | 20200618134825.487467-4-areber@redhat.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | capabilities: Introduce CAP_CHECKPOINT_RESTORE | expand |
On Thu, Jun 18, 2020 at 3:50 PM Adrian Reber <areber@redhat.com> wrote: > 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 any executable, > even setuid ones. > > This commit also changes the permission error code from -EINVAL to > -EPERM for consistency with the rest of the prctl() syscall when > checking capabilities. [...] > diff --git a/kernel/sys.c b/kernel/sys.c [...] > @@ -2007,12 +2007,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. (That is not necessarily true in the presence of LSMs like SELinux: You'd have to be able to FILE__EXECUTE_NO_TRANS the target executable according to the system's security policy.)
diff --git a/kernel/sys.c b/kernel/sys.c index 00a96746e28a..ce77012a42d7 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -2007,12 +2007,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)