|
@@ -97,10 +97,24 @@ void __ptrace_unlink(struct task_struct *child)
|
|
|
spin_unlock(&child->sighand->siglock);
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Check that we have indeed attached to the thing..
|
|
|
+/**
|
|
|
+ * ptrace_check_attach - check whether ptracee is ready for ptrace operation
|
|
|
+ * @child: ptracee to check for
|
|
|
+ * @ignore_state: don't check whether @child is currently %TASK_TRACED
|
|
|
+ *
|
|
|
+ * Check whether @child is being ptraced by %current and ready for further
|
|
|
+ * ptrace operations. If @ignore_state is %false, @child also should be in
|
|
|
+ * %TASK_TRACED state and on return the child is guaranteed to be traced
|
|
|
+ * and not executing. If @ignore_state is %true, @child can be in any
|
|
|
+ * state.
|
|
|
+ *
|
|
|
+ * CONTEXT:
|
|
|
+ * Grabs and releases tasklist_lock and @child->sighand->siglock.
|
|
|
+ *
|
|
|
+ * RETURNS:
|
|
|
+ * 0 on success, -ESRCH if %child is not ready.
|
|
|
*/
|
|
|
-int ptrace_check_attach(struct task_struct *child, int kill)
|
|
|
+int ptrace_check_attach(struct task_struct *child, bool ignore_state)
|
|
|
{
|
|
|
int ret = -ESRCH;
|
|
|
|
|
@@ -119,13 +133,13 @@ int ptrace_check_attach(struct task_struct *child, int kill)
|
|
|
*/
|
|
|
spin_lock_irq(&child->sighand->siglock);
|
|
|
WARN_ON_ONCE(task_is_stopped(child));
|
|
|
- if (task_is_traced(child) || kill)
|
|
|
+ if (task_is_traced(child) || ignore_state)
|
|
|
ret = 0;
|
|
|
spin_unlock_irq(&child->sighand->siglock);
|
|
|
}
|
|
|
read_unlock(&tasklist_lock);
|
|
|
|
|
|
- if (!ret && !kill)
|
|
|
+ if (!ret && !ignore_state)
|
|
|
ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH;
|
|
|
|
|
|
/* All systems go.. */
|