Skip to content

Commit

Permalink
Yama: allow access for the current ptrace parent
Browse files Browse the repository at this point in the history
Under ptrace_scope=1, it's possible to have a tracee that is already
ptrace-attached, but is no longer a direct descendant.  For instance, a
forking daemon will be re-parented to init, losing its ancestry to the
tracer that launched it.

The tracer can continue using ptrace in that state, but it will be
denied other accesses that check PTRACE_MODE_ATTACH, like process_vm_rw
and various procfs files.  There's no reason to prevent such access for
a tracer that already has ptrace control anyway.

This patch adds a case to ptracer_exception_found to allow access for
any task in the same thread group as the current ptrace parent.

Signed-off-by: Josh Stone <[email protected]>
Cc: Kees Cook <[email protected]>
Cc: James Morris <[email protected]>
Cc: "Serge E. Hallyn" <[email protected]>
Cc: [email protected]
Signed-off-by: Kees Cook <[email protected]>
Signed-off-by: James Morris <[email protected]>
  • Loading branch information
cuviper authored and James Morris committed Dec 5, 2016
1 parent 9430066 commit 50523a2
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion security/yama/yama_lsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ static int task_is_descendant(struct task_struct *parent,
* @tracer: the task_struct of the process attempting ptrace
* @tracee: the task_struct of the process to be ptraced
*
* Returns 1 if tracer has is ptracer exception ancestor for tracee.
* Returns 1 if tracer has a ptracer exception ancestor for tracee.
*/
static int ptracer_exception_found(struct task_struct *tracer,
struct task_struct *tracee)
Expand All @@ -320,6 +320,18 @@ static int ptracer_exception_found(struct task_struct *tracer,
bool found = false;

rcu_read_lock();

/*
* If there's already an active tracing relationship, then make an
* exception for the sake of other accesses, like process_vm_rw().
*/
parent = ptrace_parent(tracee);
if (parent != NULL && same_thread_group(parent, tracer)) {
rc = 1;
goto unlock;
}

/* Look for a PR_SET_PTRACER relationship. */
if (!thread_group_leader(tracee))
tracee = rcu_dereference(tracee->group_leader);
list_for_each_entry_rcu(relation, &ptracer_relations, node) {
Expand All @@ -334,6 +346,8 @@ static int ptracer_exception_found(struct task_struct *tracer,

if (found && (parent == NULL || task_is_descendant(parent, tracer)))
rc = 1;

unlock:
rcu_read_unlock();

return rc;
Expand Down

0 comments on commit 50523a2

Please sign in to comment.