1 /* 2 * Check decoding of sigprocmask syscall. 3 * 4 * Copyright (c) 2016-2017 Dmitry V. Levin <ldv (at) 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_sigprocmask 34 35 # include <signal.h> 36 # include <stdint.h> 37 # include <stdio.h> 38 # include <string.h> 39 # include <unistd.h> 40 41 static const char *errstr; 42 43 static long 44 k_sigprocmask(const kernel_ulong_t how, const kernel_ulong_t new_set, 45 const kernel_ulong_t old_set) 46 { 47 const long rc = syscall(__NR_sigprocmask, how, new_set, old_set); 48 errstr = sprintrc(rc); 49 return rc; 50 } 51 52 int 53 main(void) 54 { 55 static const kernel_ulong_t sig_block = 56 (kernel_ulong_t) 0xfacefeed00000000ULL | SIG_BLOCK; 57 static const kernel_ulong_t sig_unblock = 58 (kernel_ulong_t) 0xfacefeed00000000ULL | SIG_UNBLOCK; 59 static const kernel_ulong_t sig_setmask = 60 (kernel_ulong_t) 0xfacefeed00000000ULL | SIG_SETMASK; 61 62 if (k_sigprocmask(sig_setmask, 0, 0)) 63 perror_msg_and_skip("sigprocmask"); 64 puts("sigprocmask(SIG_SETMASK, NULL, NULL) = 0"); 65 66 TAIL_ALLOC_OBJECT_CONST_PTR(kernel_ulong_t, new_set); 67 TAIL_ALLOC_OBJECT_CONST_PTR(kernel_ulong_t, old_set); 68 TAIL_ALLOC_OBJECT_CONST_PTR(sigset_t, libc_set); 69 70 memset(new_set, 0, sizeof(*new_set)); 71 k_sigprocmask(sig_setmask, (uintptr_t) new_set, 0); 72 printf("sigprocmask(SIG_SETMASK, [], NULL) = %s\n", errstr); 73 74 k_sigprocmask(sig_unblock, 75 (uintptr_t) (new_set - 1), (uintptr_t) old_set); 76 puts("sigprocmask(SIG_UNBLOCK, ~[], []) = 0"); 77 78 if (F8ILL_KULONG_SUPPORTED) { 79 k_sigprocmask(sig_unblock, f8ill_ptr_to_kulong(new_set), 0); 80 printf("sigprocmask(SIG_UNBLOCK, %#jx, NULL) = %s\n", 81 (uintmax_t) f8ill_ptr_to_kulong(new_set), errstr); 82 83 k_sigprocmask(sig_unblock, 0, f8ill_ptr_to_kulong(old_set)); 84 printf("sigprocmask(SIG_UNBLOCK, NULL, %#jx) = %s\n", 85 (uintmax_t) f8ill_ptr_to_kulong(old_set), errstr); 86 } 87 88 sigemptyset(libc_set); 89 sigaddset(libc_set, SIGHUP); 90 memcpy(new_set, libc_set, sizeof(*new_set)); 91 92 k_sigprocmask(sig_block, (uintptr_t) new_set, (uintptr_t) old_set); 93 puts("sigprocmask(SIG_BLOCK, [HUP], []) = 0"); 94 95 memset(libc_set, -1, sizeof(*libc_set)); 96 sigdelset(libc_set, SIGHUP); 97 memcpy(new_set, libc_set, sizeof(*new_set)); 98 99 k_sigprocmask(sig_unblock, (uintptr_t) new_set, (uintptr_t) old_set); 100 puts("sigprocmask(SIG_UNBLOCK, ~[HUP], [HUP]) = 0"); 101 102 sigdelset(libc_set, SIGKILL); 103 memcpy(new_set, libc_set, sizeof(*new_set)); 104 105 k_sigprocmask(sig_unblock, (uintptr_t) new_set, (uintptr_t) old_set); 106 puts("sigprocmask(SIG_UNBLOCK, ~[HUP KILL], [HUP]) = 0"); 107 108 sigemptyset(libc_set); 109 sigaddset(libc_set, SIGHUP); 110 sigaddset(libc_set, SIGINT); 111 sigaddset(libc_set, SIGQUIT); 112 sigaddset(libc_set, SIGALRM); 113 sigaddset(libc_set, SIGTERM); 114 memcpy(new_set, libc_set, sizeof(*new_set)); 115 116 k_sigprocmask(sig_block, (uintptr_t) new_set, (uintptr_t) old_set); 117 printf("sigprocmask(SIG_BLOCK, %s, [HUP]) = 0\n", 118 "[HUP INT QUIT ALRM TERM]"); 119 120 k_sigprocmask(sig_setmask, 0, (uintptr_t) old_set); 121 printf("sigprocmask(SIG_SETMASK, NULL, %s) = 0\n", 122 "[HUP INT QUIT ALRM TERM]"); 123 124 k_sigprocmask(sig_setmask, (uintptr_t) (new_set + 1), 0); 125 printf("sigprocmask(SIG_SETMASK, %p, NULL) = %s\n", 126 new_set + 1, errstr); 127 128 k_sigprocmask(sig_setmask, 129 (uintptr_t) new_set, (uintptr_t) (old_set + 1)); 130 printf("sigprocmask(SIG_SETMASK, %s, %p) = %s\n", 131 "[HUP INT QUIT ALRM TERM]", old_set + 1, errstr); 132 133 uintptr_t efault = sizeof(*new_set) / 2 + (uintptr_t) new_set; 134 135 k_sigprocmask(sig_setmask, efault, 0); 136 printf("sigprocmask(SIG_SETMASK, %#jx, NULL) = %s\n", 137 (uintmax_t) efault, errstr); 138 139 k_sigprocmask(sig_setmask, 0, efault); 140 printf("sigprocmask(SIG_SETMASK, NULL, %#jx) = %s\n", 141 (uintmax_t) efault, errstr); 142 143 puts("+++ exited with 0 +++"); 144 return 0; 145 } 146 147 #else 148 149 SKIP_MAIN_UNDEFINED("__NR_sigprocmask") 150 151 #endif 152