utrace_do_stop() sets utrace->stopped but leaves the tracee in
TASK_STOPPED state. This means SIGCONT can wake up the tracee and
fool the tracer.

Set ->state = TASK_TRACED and update the comments in utrace_do_stop()
and utrace_finish_jctl().

Signed-off-by: Oleg Nesterov <o...@redhat.com>
----

 kernel/utrace.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

--- __UTRACE/kernel/utrace.c~3_STOP_TRACED      2009-07-31 02:15:34.000000000 
+0200
+++ __UTRACE/kernel/utrace.c    2009-07-31 02:25:32.000000000 +0200
@@ -788,8 +788,9 @@ static bool utrace_do_stop(struct task_s
        } else if (task_is_stopped(target)) {
                /*
                 * Stopped is considered quiescent; when it wakes up, it will
-                * go through utrace_get_signal() before doing anything else.
+                * go through utrace_finish_jctl() before doing anything else.
                 */
+               __set_task_state(target, TASK_TRACED);
                utrace->stopped = stopped = true;
        } else if (!utrace->report && !utrace->interrupt) {
                utrace->report = 1;
@@ -1646,9 +1647,8 @@ void utrace_finish_jctl(void)
 {
        struct utrace *utrace = task_utrace_struct(current);
        /*
-        * While in TASK_STOPPED, we can be considered safely
-        * stopped by utrace_do_stop(). Clear ->stopped if we
-        * were woken by signal.
+        * While in TASK_STOPPED, we can be considered safely stopped by
+        * utrace_do_stop(). Clear ->stopped if we were woken by SIGKILL.
         */
        if (utrace->stopped) {
                spin_lock(&utrace->lock);

Reply via email to