• Martin Schwidefsky's avatar
    [S390] signal race with restarting system calls · 20b40a79
    Martin Schwidefsky authored
    For a ERESTARTNOHAND/ERESTARTSYS/ERESTARTNOINTR restarting system call
    do_signal will prepare the restart of the system call with a rewind of
    the PSW before calling get_signal_to_deliver (where the debugger might
    take control). For A ERESTART_RESTARTBLOCK restarting system call
    do_signal will set -EINTR as return code.
    There are two issues with this approach:
    1) strace never sees ERESTARTNOHAND, ERESTARTSYS, ERESTARTNOINTR or
       ERESTART_RESTARTBLOCK as the rewinding already took place or the
       return code has been changed to -EINTR
    2) if get_signal_to_deliver does not return with a signal to deliver
       the restart via the repeat of the svc instruction is left in place.
       This opens a race if another signal is made pending before the
       system call instruction can be reexecuted. The original system call
       will be restarted even if the second signal would have ended the
       system call with -EINTR.
    
    These two issues can be solved by dropping the early rewind of the
    system call before get_signal_to_deliver has been called and by using
    the TIF_RESTART_SVC magic to do the restart if no signal has to be
    delivered. The only situation where the system call restart via the
    repeat of the svc instruction is appropriate is when a SA_RESTART
    signal is delivered to user space.
    
    Unfortunately this breaks inferior calls by the debugger again. The
    system call number and the length of the system call instruction is
    lost over the inferior call and user space will see ERESTARTNOHAND/
    ERESTARTSYS/ERESTARTNOINTR/ERESTART_RESTARTBLOCK. To correct this a
    new ptrace interface is added to save/restore the system call number
    and system call instruction length.
    Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
    20b40a79
ptrace.c 33.3 KB