Skip to content

Commit

Permalink
ptrace: cleanup check/set of PT_PTRACED during attach
Browse files Browse the repository at this point in the history
ptrace_attach() and ptrace_traceme() are the last functions which look as
if the untraced task can have task->ptrace != 0, this must not be
possible.  Change the code to just check ->ptrace != 0 and s/|=/=/ to set
PT_PTRACED.

Also, a couple of trivial whitespace cleanups in ptrace_attach().

And move ptrace_traceme() up near ptrace_attach() to keep them close to
each other.

Signed-off-by: Oleg Nesterov <[email protected]>
Cc: Chris Wright <[email protected]>
Acked-by: Roland McGrath <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
oleg-nesterov authored and torvalds committed Jun 18, 2009
1 parent b79b7ba commit f2f0b00
Showing 1 changed file with 51 additions and 50 deletions.
101 changes: 51 additions & 50 deletions kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,13 @@ int ptrace_attach(struct task_struct *task)
if (same_thread_group(task, current))
goto out;

/* Protect the target's credential calculations against our
/*
* Protect exec's credential calculations against our interference;
* interference; SUID, SGID and LSM creds get determined differently
* under ptrace.
*/
retval = mutex_lock_interruptible(&task->cred_guard_mutex);
if (retval < 0)
if (retval < 0)
goto out;
repeat:
/*
Expand Down Expand Up @@ -210,10 +211,10 @@ int ptrace_attach(struct task_struct *task)
retval = -EPERM;
if (unlikely(task->exit_state))
goto bad;
if (task->ptrace & PT_PTRACED)
if (task->ptrace)
goto bad;

task->ptrace |= PT_PTRACED;
task->ptrace = PT_PTRACED;
if (capable(CAP_SYS_PTRACE))
task->ptrace |= PT_PTRACE_CAP;

Expand All @@ -229,6 +230,52 @@ int ptrace_attach(struct task_struct *task)
return retval;
}

/**
* ptrace_traceme -- helper for PTRACE_TRACEME
*
* Performs checks and sets PT_PTRACED.
* Should be used by all ptrace implementations for PTRACE_TRACEME.
*/
int ptrace_traceme(void)
{
int ret = -EPERM;

/*
* Are we already being traced?
*/
repeat:
task_lock(current);
if (!current->ptrace) {
/*
* See ptrace_attach() comments about the locking here.
*/
unsigned long flags;
if (!write_trylock_irqsave(&tasklist_lock, flags)) {
task_unlock(current);
do {
cpu_relax();
} while (!write_can_lock(&tasklist_lock));
goto repeat;
}

ret = security_ptrace_traceme(current->parent);

/*
* Check PF_EXITING to ensure ->real_parent has not passed
* exit_ptrace(). Otherwise we don't report the error but
* pretend ->real_parent untraces us right after return.
*/
if (!ret && !(current->real_parent->flags & PF_EXITING)) {
current->ptrace = PT_PTRACED;
__ptrace_link(current, current->real_parent);
}

write_unlock_irqrestore(&tasklist_lock, flags);
}
task_unlock(current);
return ret;
}

/*
* Called with irqs disabled, returns true if childs should reap themselves.
*/
Expand Down Expand Up @@ -567,52 +614,6 @@ int ptrace_request(struct task_struct *child, long request,
return ret;
}

/**
* ptrace_traceme -- helper for PTRACE_TRACEME
*
* Performs checks and sets PT_PTRACED.
* Should be used by all ptrace implementations for PTRACE_TRACEME.
*/
int ptrace_traceme(void)
{
int ret = -EPERM;

/*
* Are we already being traced?
*/
repeat:
task_lock(current);
if (!(current->ptrace & PT_PTRACED)) {
/*
* See ptrace_attach() comments about the locking here.
*/
unsigned long flags;
if (!write_trylock_irqsave(&tasklist_lock, flags)) {
task_unlock(current);
do {
cpu_relax();
} while (!write_can_lock(&tasklist_lock));
goto repeat;
}

ret = security_ptrace_traceme(current->parent);

/*
* Check PF_EXITING to ensure ->real_parent has not passed
* exit_ptrace(). Otherwise we don't report the error but
* pretend ->real_parent untraces us right after return.
*/
if (!ret && !(current->real_parent->flags & PF_EXITING)) {
current->ptrace |= PT_PTRACED;
__ptrace_link(current, current->real_parent);
}

write_unlock_irqrestore(&tasklist_lock, flags);
}
task_unlock(current);
return ret;
}

/**
* ptrace_get_task_struct -- grab a task struct reference for ptrace
* @pid: process id to grab a task_struct reference of
Expand Down

0 comments on commit f2f0b00

Please sign in to comment.