Commit 9d8dad74 authored by Kees Cook's avatar Kees Cook Committed by James Morris

Yama: higher restrictions should block PTRACE_TRACEME

The higher ptrace restriction levels should be blocking even
PTRACE_TRACEME requests. The comments in the LSM documentation are
misleading about when the checks happen (the parent does not go through
security_ptrace_access_check() on a PTRACE_TRACEME call).
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Cc: stable@vger.kernel.org # 3.5.x and later
Signed-off-by: default avatarJames Morris <james.l.morris@oracle.com>
parent f4ba394c
...@@ -46,14 +46,13 @@ restrictions, it can call prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...) ...@@ -46,14 +46,13 @@ restrictions, it can call prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...)
so that any otherwise allowed process (even those in external pid namespaces) so that any otherwise allowed process (even those in external pid namespaces)
may attach. may attach.
These restrictions do not change how ptrace via PTRACE_TRACEME operates. The sysctl settings (writable only with CAP_SYS_PTRACE) are:
The sysctl settings are:
0 - classic ptrace permissions: a process can PTRACE_ATTACH to any other 0 - classic ptrace permissions: a process can PTRACE_ATTACH to any other
process running under the same uid, as long as it is dumpable (i.e. process running under the same uid, as long as it is dumpable (i.e.
did not transition uids, start privileged, or have called did not transition uids, start privileged, or have called
prctl(PR_SET_DUMPABLE...) already). prctl(PR_SET_DUMPABLE...) already). Similarly, PTRACE_TRACEME is
unchanged.
1 - restricted ptrace: a process must have a predefined relationship 1 - restricted ptrace: a process must have a predefined relationship
with the inferior it wants to call PTRACE_ATTACH on. By default, with the inferior it wants to call PTRACE_ATTACH on. By default,
...@@ -61,12 +60,13 @@ The sysctl settings are: ...@@ -61,12 +60,13 @@ The sysctl settings are:
classic criteria is also met. To change the relationship, an classic criteria is also met. To change the relationship, an
inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare
an allowed debugger PID to call PTRACE_ATTACH on the inferior. an allowed debugger PID to call PTRACE_ATTACH on the inferior.
Using PTRACE_TRACEME is unchanged.
2 - admin-only attach: only processes with CAP_SYS_PTRACE may use ptrace 2 - admin-only attach: only processes with CAP_SYS_PTRACE may use ptrace
with PTRACE_ATTACH. with PTRACE_ATTACH, or through children calling PTRACE_TRACEME.
3 - no attach: no processes may use ptrace with PTRACE_ATTACH. Once set, 3 - no attach: no processes may use ptrace with PTRACE_ATTACH nor via
this sysctl cannot be changed to a lower value. PTRACE_TRACEME. Once set, this sysctl value cannot be changed.
The original children-only logic was based on the restrictions in grsecurity. The original children-only logic was based on the restrictions in grsecurity.
......
...@@ -1242,8 +1242,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) ...@@ -1242,8 +1242,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* Check that the @parent process has sufficient permission to trace the * Check that the @parent process has sufficient permission to trace the
* current process before allowing the current process to present itself * current process before allowing the current process to present itself
* to the @parent process for tracing. * to the @parent process for tracing.
* The parent process will still have to undergo the ptrace_access_check
* checks before it is allowed to trace this one.
* @parent contains the task_struct structure for debugger process. * @parent contains the task_struct structure for debugger process.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @capget: * @capget:
......
...@@ -290,10 +290,51 @@ static int yama_ptrace_access_check(struct task_struct *child, ...@@ -290,10 +290,51 @@ static int yama_ptrace_access_check(struct task_struct *child,
return rc; return rc;
} }
/**
* yama_ptrace_traceme - validate PTRACE_TRACEME calls
* @parent: task that will become the ptracer of the current task
*
* Returns 0 if following the ptrace is allowed, -ve on error.
*/
static int yama_ptrace_traceme(struct task_struct *parent)
{
int rc;
/* If standard caps disallows it, so does Yama. We should
* only tighten restrictions further.
*/
rc = cap_ptrace_traceme(parent);
if (rc)
return rc;
/* Only disallow PTRACE_TRACEME on more aggressive settings. */
switch (ptrace_scope) {
case YAMA_SCOPE_CAPABILITY:
if (!ns_capable(task_user_ns(parent), CAP_SYS_PTRACE))
rc = -EPERM;
break;
case YAMA_SCOPE_NO_ATTACH:
rc = -EPERM;
break;
}
if (rc) {
char name[sizeof(current->comm)];
printk_ratelimited(KERN_NOTICE
"ptraceme of pid %d was attempted by: %s (pid %d)\n",
current->pid,
get_task_comm(name, parent),
parent->pid);
}
return rc;
}
static struct security_operations yama_ops = { static struct security_operations yama_ops = {
.name = "yama", .name = "yama",
.ptrace_access_check = yama_ptrace_access_check, .ptrace_access_check = yama_ptrace_access_check,
.ptrace_traceme = yama_ptrace_traceme,
.task_prctl = yama_task_prctl, .task_prctl = yama_task_prctl,
.task_free = yama_task_free, .task_free = yama_task_free,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment