1 /* 2 * Check decoding of signal syscall. 3 * 4 * Copyright (c) 2017 Dmitry V. Levin <ldv@altlinux.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "tests.h" 31 #include <asm/unistd.h> 32 33 #ifdef __NR_signal 34 35 # include <errno.h> 36 # include <signal.h> 37 # include <stdio.h> 38 # include <stdint.h> 39 # include <string.h> 40 # include <unistd.h> 41 42 static long 43 k_signal(const kernel_ulong_t signum, const kernel_ulong_t handler) 44 { 45 return syscall(__NR_signal, signum, handler); 46 } 47 48 int 49 main(void) 50 { 51 static const uintptr_t sig_ign = (uintptr_t) SIG_IGN; 52 static const uintptr_t sig_dfl = (uintptr_t) SIG_DFL; 53 static const kernel_ulong_t sigusr1 = 54 (kernel_ulong_t) 0xfacefeed00000000ULL | SIGUSR1; 55 static const struct sigaction act = { .sa_handler = SIG_DFL }; 56 long rc; 57 58 sigset_t mask; 59 sigemptyset(&mask); 60 sigaddset(&mask, SIGUSR1); 61 if (sigprocmask(SIG_BLOCK, &mask, NULL)) 62 perror_msg_and_fail("sigprocmask SIG_BLOCK"); 63 64 if (sigaction(SIGUSR1, &act, NULL)) 65 perror_msg_and_fail("sigaction"); 66 67 rc = k_signal(sigusr1, sig_ign); 68 69 if (rc == -1L) { 70 printf("signal(SIGUSR1, SIG_IGN) = %s\n", sprintrc(rc)); 71 } else if (rc != (long) sig_dfl) { 72 error_msg_and_fail("signal(SIGUSR1, SIG_IGN) = %#lx\n", rc); 73 } else { 74 printf("signal(SIGUSR1, SIG_IGN) = %#lx (SIG_DFL)\n", rc); 75 76 /* 77 * Raise and unblock SIGUSR1. 78 * If signal syscall failed to set SIGUSR1 handler to SIG_IGN, 79 * the process will be terminated by SIGUSR1. 80 */ 81 raise(SIGUSR1); 82 if (sigprocmask(SIG_UNBLOCK, &mask, NULL)) 83 perror_msg_and_fail("sigprocmask SIG_UNBLOCK"); 84 85 if (sigprocmask(SIG_BLOCK, &mask, NULL)) 86 perror_msg_and_fail("sigprocmask SIG_BLOCK"); 87 } 88 89 rc = k_signal(SIGUSR1, sig_dfl); 90 91 if (rc == -1L) { 92 printf("signal(SIGUSR1, SIG_DFL) = %s\n", sprintrc(rc)); 93 } else if (rc != (long) sig_ign) { 94 error_msg_and_fail("signal(SIGUSR1, SIG_DFL) = %#lx\n", rc); 95 } else { 96 printf("signal(SIGUSR1, SIG_DFL) = %#lx (SIG_IGN)\n", rc); 97 } 98 99 const kernel_ulong_t addr = (kernel_ulong_t) 0xfacefeeddeadbeefULL; 100 rc = k_signal(SIGUSR1, addr); 101 102 if (rc == -1L) { 103 printf("signal(SIGUSR1, %#llx) = %s\n", 104 (unsigned long long) addr, sprintrc(rc)); 105 } else if (rc != (long) sig_dfl) { 106 error_msg_and_fail("signal(SIGUSR1, %#llx) = %#lx\n", 107 (unsigned long long) addr, rc); 108 } else { 109 printf("signal(SIGUSR1, %#llx) = %#lx (SIG_DFL)\n", 110 (unsigned long long) addr, rc); 111 } 112 113 rc = k_signal(SIGUSR1, sig_ign); 114 115 if (rc == -1L) { 116 printf("signal(SIGUSR1, SIG_IGN) = %s\n", sprintrc(rc)); 117 } else { 118 printf("signal(SIGUSR1, SIG_IGN) = %#lx\n", rc); 119 } 120 121 rc = k_signal(addr, sig_ign); 122 printf("signal(%d, SIG_IGN) = %s\n", (int) addr, sprintrc(rc)); 123 124 puts("+++ exited with 0 +++"); 125 return 0; 126 } 127 128 #else 129 130 SKIP_MAIN_UNDEFINED("__NR_signal") 131 132 #endif 133