• Tejun Heo's avatar
    ptrace: Always put ptracee into appropriate execution state · 0e9f0a4a
    Tejun Heo authored
    Currently, __ptrace_unlink() wakes up the tracee iff it's in
    TASK_TRACED.  For unlinking from PTRACE_DETACH, this is correct as the
    tracee is guaranteed to be in TASK_TRACED or dead; however, unlinking
    also happens when the ptracer exits and in this case the ptracee can
    be in any state and ptrace might be left running even if the group it
    belongs to is stopped.
    
    This patch updates __ptrace_unlink() such that GROUP_STOP_PENDING is
    reinstated regardless of the ptracee's current state as long as it's
    alive and makes sure that signal_wake_up() is called if execution
    state transition is necessary.
    
    Test case follows.
    
      #include <unistd.h>
      #include <time.h>
      #include <sys/types.h>
      #include <sys/ptrace.h>
      #include <sys/wait.h>
    
      static const struct timespec ts1s = { .tv_sec = 1 };
    
      int main(void)
      {
    	  pid_t tracee;
    	  siginfo_t si;
    
    	  tracee = fork();
    	  if (tracee == 0) {
    		  while (1) {
    			  nanosleep(&ts1s, NULL);
    			  write(1, ".", 1);
    		  }
    	  }
    
    	  ptrace(PTRACE_ATTACH, tracee, NULL, NULL);
    	  waitid(P_PID, tracee, &si, WSTOPPED);
    	  ptrace(PTRACE_CONT, tracee, NULL, (void *)(long)si.si_status);
    	  waitid(P_PID, tracee, &si, WSTOPPED);
    	  ptrace(PTRACE_CONT, tracee, NULL, (void *)(long)si.si_status);
    	  write(1, "exiting", 7);
    	  return 0;
      }
    
    Before the patch, after the parent process exits, the child is left
    running and prints out "." every second.
    
      exiting..... (continues)
    
    After the patch, the group stop initiated by the implied SIGSTOP from
    PTRACE_ATTACH is re-established when the parent exits.
    
      exiting
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Reported-by: default avatarOleg Nesterov <oleg@redhat.com>
    Acked-by: default avatarOleg Nesterov <oleg@redhat.com>
    0e9f0a4a
ptrace.c 22.3 KB