From 0bcfa7b5cb3c837f717219be6f0d254f3c745342 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Sun, 28 May 2017 17:13:29 +0000 Subject: [PATCH] tests: check decoding of sigaction syscall * tests/sigaction.c: New file. * tests/gen_tests.in (sigaction): New entry. * tests/pure_executables.list: Add sigaction. * tests/.gitignore: Likewise. --- tests/.gitignore | 1 + tests/gen_tests.in | 1 + tests/pure_executables.list | 1 + tests/sigaction.c | 199 ++++++++++++++++++++++++++++++++++++ 4 files changed, 202 insertions(+) create mode 100644 tests/sigaction.c diff --git a/tests/.gitignore b/tests/.gitignore index d24d270d..af2bf0eb 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -326,6 +326,7 @@ setuid setuid32 shmxt shutdown +sigaction sigaltstack siginfo signal diff --git a/tests/gen_tests.in b/tests/gen_tests.in index 89f7737f..8f154309 100644 --- a/tests/gen_tests.in +++ b/tests/gen_tests.in @@ -280,6 +280,7 @@ setuid -a10 setuid32 -a12 shmxt -a11 -e trace='/(osf_)?shmat,shmdt' shutdown -a24 +sigaction -a31 siginfo -e trace=none signal -a25 -e signal=none -e trace='/^signal$' signal_receive -a16 -e trace=kill diff --git a/tests/pure_executables.list b/tests/pure_executables.list index cd759b00..eb7ce4ca 100755 --- a/tests/pure_executables.list +++ b/tests/pure_executables.list @@ -267,6 +267,7 @@ setuid setuid32 shmxt shutdown +sigaction sigaltstack siginfo signal diff --git a/tests/sigaction.c b/tests/sigaction.c new file mode 100644 index 00000000..644df794 --- /dev/null +++ b/tests/sigaction.c @@ -0,0 +1,199 @@ +/* + * Check decoding of sigaction syscall. + * + * Copyright (c) 2017 Dmitry V. Levin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "tests.h" +#include + +#ifdef __NR_sigaction + +# include +# include +# include +# include +# include + +struct set_sa { +#if defined MIPS + unsigned int flags; + unsigned long handler; + unsigned long mask[1]; +#elif defined ALPHA + unsigned long handler; + unsigned long mask[1]; + unsigned int flags; +#else + unsigned long handler; + unsigned long mask[1]; + unsigned long flags; + unsigned long restorer; +#endif +} +#ifdef ALPHA + ATTRIBUTE_PACKED +#endif +; + +typedef struct set_sa struct_set_sa; + +#ifdef MIPS + +struct get_sa { + unsigned int flags; + unsigned long handler; + unsigned long mask[4]; +}; + +typedef struct get_sa struct_get_sa; + +#else + +typedef struct set_sa struct_get_sa; + +#endif + +static long +k_sigaction(const kernel_ulong_t signum, const kernel_ulong_t new_act, + const kernel_ulong_t old_act) +{ + return syscall(__NR_sigaction, signum, new_act, old_act); +} + +#if defined SPARC || defined SPARC64 +static const kernel_ulong_t signo = + (kernel_ulong_t) 0xbadc0ded00000000ULL | (unsigned int) -SIGUSR1; +# define SIG_STR "-SIGUSR1" +#else +static const kernel_ulong_t signo = + (kernel_ulong_t) 0xbadc0ded00000000ULL | SIGUSR1; +# define SIG_STR "SIGUSR1" +#endif + +int +main(void) +{ + static const kernel_ulong_t addr = + (kernel_ulong_t) 0xfacefeed0defacedULL; + union { + sigset_t libc[1]; + unsigned long old[1]; + } mask; + + TAIL_ALLOC_OBJECT_CONST_PTR(struct_set_sa, new_act); + TAIL_ALLOC_OBJECT_CONST_PTR(struct_get_sa, old_act); + + if (k_sigaction(signo, 0, 0)) + perror_msg_and_skip("sigaction"); + puts("sigaction(" SIG_STR ", NULL, NULL) = 0"); + + k_sigaction(signo, 0, 0); + puts("sigaction(" SIG_STR ", NULL, NULL) = 0"); + + k_sigaction(signo, (uintptr_t) (new_act + 1), 0); + printf("sigaction(" SIG_STR ", %p, NULL) = -1 EFAULT (%m)\n", + new_act + 1); + + k_sigaction(signo, (uintptr_t) new_act + 2, 0); + printf("sigaction(" SIG_STR ", %#lx, NULL) = -1 EFAULT (%m)\n", + (unsigned long) new_act + 2); + + k_sigaction(signo, 0, (uintptr_t) (old_act + 1)); + printf("sigaction(" SIG_STR ", NULL, %p) = -1 EFAULT (%m)\n", + old_act + 1); + + k_sigaction(signo, 0, (uintptr_t) old_act + 2); + printf("sigaction(" SIG_STR ", NULL, %#lx) = -1 EFAULT (%m)\n", + (unsigned long) old_act + 2); + + k_sigaction(addr, 0, 0); + printf("sigaction(%d, NULL, NULL) = -1 EINVAL (%m)\n", (int) addr); + + memset(new_act, 0, sizeof(*new_act)); + + k_sigaction(signo, (uintptr_t) new_act, 0); + puts("sigaction(" SIG_STR ", {sa_handler=SIG_DFL, sa_mask=[]" + ", sa_flags=0}, NULL) = 0"); + + sigemptyset(mask.libc); + sigaddset(mask.libc, SIGHUP); + sigaddset(mask.libc, SIGINT); + + new_act->handler = (uintptr_t) SIG_IGN; + memcpy(new_act->mask, mask.old, sizeof(mask.old)); + new_act->flags = SA_SIGINFO; + + k_sigaction(signo, (uintptr_t) new_act, (uintptr_t) old_act); + puts("sigaction(" SIG_STR ", {sa_handler=SIG_IGN, sa_mask=[HUP INT]" + ", sa_flags=SA_SIGINFO}, {sa_handler=SIG_DFL, sa_mask=[]" + ", sa_flags=0}) = 0"); + + sigemptyset(mask.libc); + sigaddset(mask.libc, SIGQUIT); + sigaddset(mask.libc, SIGTERM); + + new_act->handler = (unsigned long) addr; + memcpy(new_act->mask, mask.old, sizeof(mask.old)); + new_act->flags = SA_ONSTACK | SA_RESTART; + + k_sigaction(signo, (uintptr_t) new_act, (uintptr_t) old_act); + printf("sigaction(" SIG_STR ", {sa_handler=%#lx, sa_mask=[QUIT TERM]" + ", sa_flags=SA_ONSTACK|SA_RESTART}, {sa_handler=SIG_IGN" + ", sa_mask=[HUP INT], sa_flags=SA_SIGINFO}) = 0\n", + new_act->handler); + + memset(mask.old, -1, sizeof(mask.old)); + sigdelset(mask.libc, SIGHUP); + + memcpy(new_act->mask, mask.old, sizeof(mask.old)); +#ifdef SA_RESTORER + new_act->flags = SA_RESTORER; + new_act->restorer = (unsigned long) 0xdeadfacecafef00dULL; +# define SA_RESTORER_FMT ", sa_flags=SA_RESTORER, sa_restorer=%#lx" +# define SA_RESTORER_ARGS ,new_act->restorer +#else + new_act->flags = SA_NODEFER; +# define SA_RESTORER_FMT ", sa_flags=SA_NODEFER" +# define SA_RESTORER_ARGS +#endif + + k_sigaction(signo, (uintptr_t) new_act, (uintptr_t) old_act); + printf("sigaction(" SIG_STR ", {sa_handler=%#lx, sa_mask=~[HUP]" + SA_RESTORER_FMT "}, {sa_handler=%#lx, sa_mask=[QUIT TERM]" + ", sa_flags=SA_ONSTACK|SA_RESTART}) = 0\n", + new_act->handler SA_RESTORER_ARGS, + new_act->handler); + + puts("+++ exited with 0 +++"); + return 0; +} + +#else + +SKIP_MAIN_UNDEFINED("__NR_sigaction") + +#endif -- 2.40.0