• Sven Schnelle's avatar
    s390/signal: switch to using vdso for sigreturn and syscall restart · df29a744
    Sven Schnelle authored
    with generic entry, there's a bug when it comes to restarting of signals.
    The failing sequence is:
    
    a) a signal is coming in, and no handler is registered, so the lower
       part of arch_do_signal_or_restart() in arch/s390/kernel/signal.c
       sets PIF_SYSCALL_RESTART.
    
    b) a second signal gets pending while the kernel is still in the exit
       loop, and for that one, a handler exists.
    
    c) The first part of arch_do_signal_or_restart() is called. That part
       calls handle_signal(), which sets up stack + registers for handling
       the signal.
    
    d) __do_syscall() in arch/s390/kernel/syscall.c checks for
       PIF_SYSCALL_RESTART right before leaving to userspace. If it is set,
       it restart's the syscall. However, the registers are already setup
       for handling a signal from c). The syscall is now restarted with the
       wrong arguments.
    
    Change the code to:
    
    - use vdso for syscall_restart() instead of PIF_SYSCALL_RESTART because
      we cannot rewind and go back to userspace on s390 because the system call
      number might be encoded in the svc instruction.
    - for all other syscalls we rewind the PSW and return to userspace.
    
    Cc: <stable@kernel.org> # v5.12+ d57778fe: s390/vdso: always enable vdso
    Cc: <stable@kernel.org> # v5.12+ 686341f2: s390/vdso64: add sigreturn,rt_sigreturn and restart_syscall
    Cc: <stable@kernel.org> # v5.12+ 43e1f76b: s390/vdso: rename VDSO64_LBASE to VDSO_LBASE
    Cc: <stable@kernel.org> # v5.12+ 779df224: s390/vdso: add minimal compat vdso
    Cc: <stable@kernel.org> # v5.12+
    Signed-off-by: default avatarSven Schnelle <svens@linux.ibm.com>
    Reviewed-by: default avatarHeiko Carstens <hca@linux.ibm.com>
    Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
    df29a744
signal.c 15.6 KB