• Roman Gushchin's avatar
    signal: unconditionally leave the frozen state in ptrace_stop() · 05b28926
    Roman Gushchin authored
    Alex Xu reported a regression in strace, caused by the introduction of
    the cgroup v2 freezer. The regression can be reproduced by stracing
    the following simple program:
    
      #include <unistd.h>
    
      int main() {
          write(1, "a", 1);
          return 0;
      }
    
    An attempt to run strace ./a.out leads to the infinite loop:
      [ pre-main omitted ]
      write(1, "a", 1)                        = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
      write(1, "a", 1)                        = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
      write(1, "a", 1)                        = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
      write(1, "a", 1)                        = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
      write(1, "a", 1)                        = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
      write(1, "a", 1)                        = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
      [ repeats forever ]
    
    The problem occurs because the traced task leaves ptrace_stop()
    (and the signal handling loop) with the frozen bit set. So let's
    call cgroup_leave_frozen(true) unconditionally after sleeping
    in ptrace_stop().
    
    With this patch applied, strace works as expected:
      [ pre-main omitted ]
      write(1, "a", 1)                        = 1
      exit_group(0)                           = ?
      +++ exited with 0 +++
    Reported-by: default avatarAlex Xu <alex_y_xu@yahoo.ca>
    Fixes: 76f969e8 ("cgroup: cgroup v2 freezer")
    Signed-off-by: default avatarRoman Gushchin <guro@fb.com>
    Acked-by: default avatarOleg Nesterov <oleg@redhat.com>
    Cc: Tejun Heo <tj@kernel.org>
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    05b28926
signal.c 115 KB