diff --git a/arch/sw_64/Kconfig b/arch/sw_64/Kconfig index deefaf312628a94815b76b60bf1d4ec1f5d04def..392f7806afcb2ce9b1f540ca432bc6c85be36738 100644 --- a/arch/sw_64/Kconfig +++ b/arch/sw_64/Kconfig @@ -23,7 +23,6 @@ config SW64 select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_SECCOMP_FILTER - select OLD_SIGACTION select OLD_SIGSUSPEND select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER diff --git a/arch/sw_64/include/asm/signal.h b/arch/sw_64/include/asm/signal.h index 3e91b72c0b0a8af9c0803cc8d0257a1f917e4f77..0d846c1aa571e5ea946d7ef9422ba63d77d3bd30 100644 --- a/arch/sw_64/include/asm/signal.h +++ b/arch/sw_64/include/asm/signal.h @@ -14,9 +14,11 @@ typedef struct { unsigned long sig[_NSIG_WORDS]; } sigset_t; -#ifdef CONFIG_OLD_SIGACTION -#define __ARCH_HAS_SA_RESTORER -#endif +struct odd_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + int sa_flags; +}; #include #endif diff --git a/arch/sw_64/kernel/signal.c b/arch/sw_64/kernel/signal.c index 6a6203ccb04f489ef0b6b1bbf59b4635c3f88d50..a1edc5300742af8936b4abaf6a21f459fbc0a27d 100644 --- a/arch/sw_64/kernel/signal.c +++ b/arch/sw_64/kernel/signal.c @@ -38,6 +38,36 @@ SYSCALL_DEFINE2(odd_sigprocmask, int, how, unsigned long, newmask) return res; } +SYSCALL_DEFINE3(odd_sigaction, int, sig, + const struct odd_sigaction __user *, act, + struct odd_sigaction __user *, oact) +{ + struct k_sigaction new_ka, old_ka; + old_sigset_t mask; + int ret; + + if (act) { + if (!access_ok(act, sizeof(*act)) || + __get_user(new_ka.sa.sa_handler, &act->sa_handler) || + __get_user(new_ka.sa.sa_flags, &act->sa_flags) || + __get_user(mask, &act->sa_mask)) + return -EFAULT; + siginitset(&new_ka.sa.sa_mask, mask); + } + + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + + if (!ret && oact) { + if (!access_ok(oact, sizeof(*oact)) || + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || + __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) + return -EFAULT; + } + + return ret; +} + /* * Do a signal return; undo the signal stack. */ diff --git a/arch/sw_64/kernel/syscalls/syscall.tbl b/arch/sw_64/kernel/syscalls/syscall.tbl index 42a179422b6b22fbe14fa10237dfb93ba6dc9261..35d108b49a61ca7ac1058272e89dc2ecacf61923 100644 --- a/arch/sw_64/kernel/syscalls/syscall.tbl +++ b/arch/sw_64/kernel/syscalls/syscall.tbl @@ -163,7 +163,7 @@ #153 is unused #154 is unused #155 is unused -156 common sigaction sys_sigaction +156 common sigaction sys_odd_sigaction #157 is unused #158 is unused #159 is unused