139bac055674d23770b9a724221b728e443196ea7Elliott Hughes/* 239bac055674d23770b9a724221b728e443196ea7Elliott Hughes * Check decoding of sigsuspend syscall. 339bac055674d23770b9a724221b728e443196ea7Elliott Hughes * 439bac055674d23770b9a724221b728e443196ea7Elliott Hughes * Copyright (c) 2017 Dmitry V. Levin <ldv@altlinux.org> 539bac055674d23770b9a724221b728e443196ea7Elliott Hughes * All rights reserved. 639bac055674d23770b9a724221b728e443196ea7Elliott Hughes * 739bac055674d23770b9a724221b728e443196ea7Elliott Hughes * Redistribution and use in source and binary forms, with or without 839bac055674d23770b9a724221b728e443196ea7Elliott Hughes * modification, are permitted provided that the following conditions 939bac055674d23770b9a724221b728e443196ea7Elliott Hughes * are met: 1039bac055674d23770b9a724221b728e443196ea7Elliott Hughes * 1. Redistributions of source code must retain the above copyright 1139bac055674d23770b9a724221b728e443196ea7Elliott Hughes * notice, this list of conditions and the following disclaimer. 1239bac055674d23770b9a724221b728e443196ea7Elliott Hughes * 2. Redistributions in binary form must reproduce the above copyright 1339bac055674d23770b9a724221b728e443196ea7Elliott Hughes * notice, this list of conditions and the following disclaimer in the 1439bac055674d23770b9a724221b728e443196ea7Elliott Hughes * documentation and/or other materials provided with the distribution. 1539bac055674d23770b9a724221b728e443196ea7Elliott Hughes * 3. The name of the author may not be used to endorse or promote products 1639bac055674d23770b9a724221b728e443196ea7Elliott Hughes * derived from this software without specific prior written permission. 1739bac055674d23770b9a724221b728e443196ea7Elliott Hughes * 1839bac055674d23770b9a724221b728e443196ea7Elliott Hughes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1939bac055674d23770b9a724221b728e443196ea7Elliott Hughes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2039bac055674d23770b9a724221b728e443196ea7Elliott Hughes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2139bac055674d23770b9a724221b728e443196ea7Elliott Hughes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2239bac055674d23770b9a724221b728e443196ea7Elliott Hughes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2339bac055674d23770b9a724221b728e443196ea7Elliott Hughes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2439bac055674d23770b9a724221b728e443196ea7Elliott Hughes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2539bac055674d23770b9a724221b728e443196ea7Elliott Hughes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2639bac055674d23770b9a724221b728e443196ea7Elliott Hughes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2739bac055674d23770b9a724221b728e443196ea7Elliott Hughes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2839bac055674d23770b9a724221b728e443196ea7Elliott Hughes */ 2939bac055674d23770b9a724221b728e443196ea7Elliott Hughes 3039bac055674d23770b9a724221b728e443196ea7Elliott Hughes#include "tests.h" 3139bac055674d23770b9a724221b728e443196ea7Elliott Hughes#include <asm/unistd.h> 3239bac055674d23770b9a724221b728e443196ea7Elliott Hughes 3339bac055674d23770b9a724221b728e443196ea7Elliott Hughes#ifdef __NR_sigsuspend 3439bac055674d23770b9a724221b728e443196ea7Elliott Hughes 3539bac055674d23770b9a724221b728e443196ea7Elliott Hughes# include <assert.h> 3639bac055674d23770b9a724221b728e443196ea7Elliott Hughes# include <errno.h> 3739bac055674d23770b9a724221b728e443196ea7Elliott Hughes# include <signal.h> 3839bac055674d23770b9a724221b728e443196ea7Elliott Hughes# include <stdio.h> 3939bac055674d23770b9a724221b728e443196ea7Elliott Hughes# include <stdint.h> 4039bac055674d23770b9a724221b728e443196ea7Elliott Hughes# include <string.h> 4139bac055674d23770b9a724221b728e443196ea7Elliott Hughes# include <unistd.h> 4239bac055674d23770b9a724221b728e443196ea7Elliott Hughes 4339bac055674d23770b9a724221b728e443196ea7Elliott Hughes# ifdef MIPS 4439bac055674d23770b9a724221b728e443196ea7Elliott Hughes# define SIGNAL_MASK_BY_REF 1 4539bac055674d23770b9a724221b728e443196ea7Elliott Hughes# else 4639bac055674d23770b9a724221b728e443196ea7Elliott Hughes# define SIGNAL_MASK_BY_REF 0 4739bac055674d23770b9a724221b728e443196ea7Elliott Hughes# endif 4839bac055674d23770b9a724221b728e443196ea7Elliott Hughes 4939bac055674d23770b9a724221b728e443196ea7Elliott Hughesstatic long 5039bac055674d23770b9a724221b728e443196ea7Elliott Hughesk_sigsuspend(const kernel_ulong_t arg1, 5139bac055674d23770b9a724221b728e443196ea7Elliott Hughes const kernel_ulong_t arg2, 5239bac055674d23770b9a724221b728e443196ea7Elliott Hughes const kernel_ulong_t arg3) 5339bac055674d23770b9a724221b728e443196ea7Elliott Hughes{ 5439bac055674d23770b9a724221b728e443196ea7Elliott Hughes return syscall(__NR_sigsuspend, arg1, arg2, arg3); 5539bac055674d23770b9a724221b728e443196ea7Elliott Hughes} 5639bac055674d23770b9a724221b728e443196ea7Elliott Hughes 5739bac055674d23770b9a724221b728e443196ea7Elliott Hughesstatic int signo; 5839bac055674d23770b9a724221b728e443196ea7Elliott Hughesstatic const char *sigtxt[] = { 5939bac055674d23770b9a724221b728e443196ea7Elliott Hughes [SIGUSR1] = "USR1", 6039bac055674d23770b9a724221b728e443196ea7Elliott Hughes [SIGUSR2] = "USR2" 6139bac055674d23770b9a724221b728e443196ea7Elliott Hughes}; 6239bac055674d23770b9a724221b728e443196ea7Elliott Hughes 6339bac055674d23770b9a724221b728e443196ea7Elliott Hughesstatic void 6439bac055674d23770b9a724221b728e443196ea7Elliott Hugheshandler(int i) 6539bac055674d23770b9a724221b728e443196ea7Elliott Hughes{ 6639bac055674d23770b9a724221b728e443196ea7Elliott Hughes signo = i; 6739bac055674d23770b9a724221b728e443196ea7Elliott Hughes} 6839bac055674d23770b9a724221b728e443196ea7Elliott Hughes 6939bac055674d23770b9a724221b728e443196ea7Elliott Hughesint 7039bac055674d23770b9a724221b728e443196ea7Elliott Hughesmain(void) 7139bac055674d23770b9a724221b728e443196ea7Elliott Hughes{ 7239bac055674d23770b9a724221b728e443196ea7Elliott Hughes union { 7339bac055674d23770b9a724221b728e443196ea7Elliott Hughes sigset_t libc_mask; 7439bac055674d23770b9a724221b728e443196ea7Elliott Hughes unsigned long old_mask; 7539bac055674d23770b9a724221b728e443196ea7Elliott Hughes } u; 7639bac055674d23770b9a724221b728e443196ea7Elliott Hughes 7739bac055674d23770b9a724221b728e443196ea7Elliott Hughes sigemptyset(&u.libc_mask); 7839bac055674d23770b9a724221b728e443196ea7Elliott Hughes sigaddset(&u.libc_mask, SIGUSR1); 7939bac055674d23770b9a724221b728e443196ea7Elliott Hughes sigaddset(&u.libc_mask, SIGUSR2); 8039bac055674d23770b9a724221b728e443196ea7Elliott Hughes if (sigprocmask(SIG_SETMASK, &u.libc_mask, NULL)) 8139bac055674d23770b9a724221b728e443196ea7Elliott Hughes perror_msg_and_fail("sigprocmask"); 8239bac055674d23770b9a724221b728e443196ea7Elliott Hughes 8339bac055674d23770b9a724221b728e443196ea7Elliott Hughes const struct sigaction sa = { .sa_handler = handler }; 8439bac055674d23770b9a724221b728e443196ea7Elliott Hughes if (sigaction(SIGUSR1, &sa, NULL) || sigaction(SIGUSR2, &sa, NULL)) 8539bac055674d23770b9a724221b728e443196ea7Elliott Hughes perror_msg_and_fail("sigaction"); 8639bac055674d23770b9a724221b728e443196ea7Elliott Hughes 8739bac055674d23770b9a724221b728e443196ea7Elliott Hughes raise(SIGUSR1); 8839bac055674d23770b9a724221b728e443196ea7Elliott Hughes raise(SIGUSR2); 8939bac055674d23770b9a724221b728e443196ea7Elliott Hughes 9039bac055674d23770b9a724221b728e443196ea7Elliott Hughes u.old_mask = -1UL; 9139bac055674d23770b9a724221b728e443196ea7Elliott Hughes sigdelset(&u.libc_mask, SIGUSR1); 9239bac055674d23770b9a724221b728e443196ea7Elliott Hughes const unsigned long mask1 = u.old_mask; 9339bac055674d23770b9a724221b728e443196ea7Elliott Hughes 9439bac055674d23770b9a724221b728e443196ea7Elliott Hughes u.old_mask = -1UL; 9539bac055674d23770b9a724221b728e443196ea7Elliott Hughes sigdelset(&u.libc_mask, SIGUSR2); 9639bac055674d23770b9a724221b728e443196ea7Elliott Hughes const unsigned long mask2 = u.old_mask; 9739bac055674d23770b9a724221b728e443196ea7Elliott Hughes 9839bac055674d23770b9a724221b728e443196ea7Elliott Hughes#if SIGNAL_MASK_BY_REF 9939bac055674d23770b9a724221b728e443196ea7Elliott Hughes k_sigsuspend((uintptr_t) &mask1, 0xdeadbeef, (uintptr_t) &mask2); 10039bac055674d23770b9a724221b728e443196ea7Elliott Hughes#else 10139bac055674d23770b9a724221b728e443196ea7Elliott Hughes k_sigsuspend(mask1, 0xdeadbeef, mask2); 10239bac055674d23770b9a724221b728e443196ea7Elliott Hughes#endif 10339bac055674d23770b9a724221b728e443196ea7Elliott Hughes if (EINTR != errno) 10439bac055674d23770b9a724221b728e443196ea7Elliott Hughes perror_msg_and_skip("sigsuspend"); 10539bac055674d23770b9a724221b728e443196ea7Elliott Hughes 10639bac055674d23770b9a724221b728e443196ea7Elliott Hughes printf("sigsuspend(~[%s]) = ? ERESTARTNOHAND" 10739bac055674d23770b9a724221b728e443196ea7Elliott Hughes " (To be restarted if no handler)\n", sigtxt[signo]); 10839bac055674d23770b9a724221b728e443196ea7Elliott Hughes 10939bac055674d23770b9a724221b728e443196ea7Elliott Hughes puts("+++ exited with 0 +++"); 11039bac055674d23770b9a724221b728e443196ea7Elliott Hughes return 0; 11139bac055674d23770b9a724221b728e443196ea7Elliott Hughes} 11239bac055674d23770b9a724221b728e443196ea7Elliott Hughes 11339bac055674d23770b9a724221b728e443196ea7Elliott Hughes#else 11439bac055674d23770b9a724221b728e443196ea7Elliott Hughes 11539bac055674d23770b9a724221b728e443196ea7Elliott HughesSKIP_MAIN_UNDEFINED("__NR_sigsuspend") 11639bac055674d23770b9a724221b728e443196ea7Elliott Hughes 11739bac055674d23770b9a724221b728e443196ea7Elliott Hughes#endif 118