1 /* 2 * Check decoding of sgetmask and ssetmask syscalls. 3 * 4 * Copyright (c) 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 #if defined __NR_sgetmask && defined __NR_ssetmask 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_sgetmask(void) 44 { 45 return syscall(__NR_sgetmask); 46 } 47 48 static long 49 k_ssetmask(const kernel_ulong_t arg) 50 { 51 return syscall(__NR_ssetmask, arg); 52 } 53 54 int 55 main(void) 56 { 57 union { 58 sigset_t libc_mask; 59 unsigned long old_mask; 60 } uset, uget; 61 long rc; 62 63 /* 64 * Block, reset, and raise SIGUSR1. 65 * If a subsequent ssetmask call fails to set the proper mask, 66 * the process will be terminated by SIGUSR1. 67 */ 68 sigemptyset(&uset.libc_mask); 69 sigaddset(&uset.libc_mask, SIGUSR1); 70 if (sigprocmask(SIG_SETMASK, &uset.libc_mask, NULL)) 71 perror_msg_and_fail("sigprocmask"); 72 if (signal(SIGUSR1, SIG_DFL) == SIG_ERR) 73 perror_msg_and_fail("signal"); 74 raise(SIGUSR1); 75 76 sigaddset(&uset.libc_mask, SIGUSR2); 77 rc = k_ssetmask((kernel_ulong_t) 0xfacefeed00000000ULL | uset.old_mask); 78 if (rc == -1L) { 79 printf("ssetmask([USR1 USR2]) = %s\n", sprintrc(rc)); 80 } else { 81 printf("ssetmask([USR1 USR2]) = %#lx (old mask [USR1])\n", rc); 82 /* 83 * Use a regular sigprocmask call to check the value 84 * returned by the ssetmask call being tested. 85 */ 86 if (sigprocmask(SIG_SETMASK, NULL, &uget.libc_mask)) 87 perror_msg_and_fail("sigprocmask"); 88 if (uset.old_mask != uget.old_mask) 89 error_msg_and_fail("sigprocmask returned %#lx" 90 " instead of %#lx", 91 uget.old_mask, uset.old_mask); 92 } 93 94 rc = k_sgetmask(); 95 if (rc == -1L) { 96 printf("sgetmask() = %s\n", sprintrc(rc)); 97 } else { 98 printf("sgetmask() = %#lx (mask [USR1 USR2])\n", rc); 99 if (uget.old_mask != (unsigned long) rc) 100 error_msg_and_fail("sigprocmask returned %#lx", 101 uget.old_mask); 102 103 if (sizeof(long) > 4) { 104 sigaddset(&uset.libc_mask, 32 + 27); 105 if (sigprocmask(SIG_SETMASK, &uset.libc_mask, NULL)) 106 perror_msg_and_fail("sigprocmask"); 107 rc = k_sgetmask(); 108 printf("sgetmask() = %#lx" 109 " (mask [USR1 USR2 RT_27])\n", rc); 110 if (uset.old_mask != (unsigned long) rc) 111 error_msg_and_fail("sigprocmask set %#lx", 112 uset.old_mask); 113 } 114 } 115 116 puts("+++ exited with 0 +++"); 117 return 0; 118 } 119 120 #else 121 122 SKIP_MAIN_UNDEFINED("__NR_sgetmask && __NR_ssetmask") 123 124 #endif 125