Skip to content

Commit

Permalink
Yama: higher restrictions should block PTRACE_TRACEME
Browse files Browse the repository at this point in the history
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: Kees Cook <[email protected]>
Cc: [email protected] # 3.5.x and later
Signed-off-by: James Morris <[email protected]>
  • Loading branch information
kees authored and James Morris committed Aug 10, 2012
1 parent f4ba394 commit 9d8dad7
Showing 3 changed files with 48 additions and 9 deletions.
14 changes: 7 additions & 7 deletions Documentation/security/Yama.txt
Original file line number Diff line number Diff line change
@@ -46,27 +46,27 @@ restrictions, it can call prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...)
so that any otherwise allowed process (even those in external pid namespaces)
may attach.

These restrictions do not change how ptrace via PTRACE_TRACEME operates.

The sysctl settings are:
The sysctl settings (writable only with CAP_SYS_PTRACE) are:

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.
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
with the inferior it wants to call PTRACE_ATTACH on. By default,
this relationship is that of only its descendants when the above
classic criteria is also met. To change the relationship, an
inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare
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
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,
this sysctl cannot be changed to a lower value.
3 - no attach: no processes may use ptrace with PTRACE_ATTACH nor via
PTRACE_TRACEME. Once set, this sysctl value cannot be changed.

The original children-only logic was based on the restrictions in grsecurity.

2 changes: 0 additions & 2 deletions include/linux/security.h
Original file line number Diff line number Diff line change
@@ -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
* current process before allowing the current process to present itself
* 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.
* Return 0 if permission is granted.
* @capget:
41 changes: 41 additions & 0 deletions security/yama/yama_lsm.c
Original file line number Diff line number Diff line change
@@ -290,10 +290,51 @@ static int yama_ptrace_access_check(struct task_struct *child,
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 = {
.name = "yama",

.ptrace_access_check = yama_ptrace_access_check,
.ptrace_traceme = yama_ptrace_traceme,
.task_prctl = yama_task_prctl,
.task_free = yama_task_free,
};

0 comments on commit 9d8dad7

Please sign in to comment.