1 /* $OpenBSD: t_sigaction.c,v 1.2 2021/12/13 16:56:48 deraadt Exp $ */ 2 /* $NetBSD: t_sigaction.c,v 1.5 2017/01/13 21:30:41 christos Exp $ */ 3 4 /*- 5 * Copyright (c) 2010 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "macros.h" 31 32 #include <sys/wait.h> 33 34 #include <signal.h> 35 #include <stdbool.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <unistd.h> 39 40 #include "atf-c.h" 41 42 #include "h_macros.h" 43 44 static bool handler_called = false; 45 46 static void 47 handler(int signo __unused) 48 { 49 handler_called = true; 50 } 51 52 static void 53 sa_resethand_child(const int flags) 54 { 55 struct sigaction sa; 56 57 sa.sa_flags = flags; 58 sa.sa_handler = &handler; 59 sigemptyset(&sa.sa_mask); 60 61 sigaction(SIGUSR1, &sa, NULL); 62 kill(getpid(), SIGUSR1); 63 exit(handler_called ? EXIT_SUCCESS : EXIT_FAILURE); 64 } 65 66 static void 67 wait_and_check_child(const pid_t pid, const char *fail_message) 68 { 69 int status; 70 71 (void)waitpid(pid, &status, 0); 72 73 if (WIFEXITED(status)) 74 ATF_CHECK_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); 75 else 76 atf_tc_fail("%s; raw exit status was %d", fail_message, status); 77 } 78 79 static void 80 catch(int sig __unused) 81 { 82 return; 83 } 84 85 ATF_TC(sigaction_basic); 86 ATF_TC_HEAD(sigaction_basic, tc) 87 { 88 89 atf_tc_set_md_var(tc, "descr", "Checks for correct I&D cache" 90 "synchronization after copying out the trampoline code."); 91 } 92 93 ATF_TC_BODY(sigaction_basic, tc) 94 { 95 static struct sigaction sa; 96 97 sa.sa_handler = catch; 98 99 sigaction(SIGUSR1, &sa, 0); 100 kill(getpid(), SIGUSR1); 101 atf_tc_pass(); 102 } 103 104 ATF_TC(sigaction_noflags); 105 ATF_TC_HEAD(sigaction_noflags, tc) 106 { 107 atf_tc_set_md_var(tc, "descr", "Checks programming a signal with " 108 "sigaction(2) but without any flags"); 109 } 110 111 ATF_TC_BODY(sigaction_noflags, tc) 112 { 113 const pid_t pid = fork(); 114 if (pid == -1) 115 atf_tc_fail_errno("fork(2) failed"); 116 else if (pid == 0) 117 sa_resethand_child(0); 118 else 119 wait_and_check_child(pid, "Child process did not exit cleanly;" 120 " it failed to process the signal"); 121 } 122 123 ATF_TC(sigaction_resethand); 124 ATF_TC_HEAD(sigaction_resethand, tc) 125 { 126 atf_tc_set_md_var(tc, "descr", "Checks that SA_RESETHAND works"); 127 } 128 129 ATF_TC_BODY(sigaction_resethand, tc) 130 { 131 const pid_t pid = fork(); 132 if (pid == -1) 133 atf_tc_fail_errno("fork(2) failed"); 134 else if (pid == 0) 135 sa_resethand_child(SA_RESETHAND); 136 else { 137 wait_and_check_child(pid, "Child process did not exit cleanly;" 138 " it either failed to process the signal or SA_RESETHAND" 139 " is broken"); 140 } 141 } 142 143 ATF_TP_ADD_TCS(tp) 144 { 145 146 ATF_TP_ADD_TC(tp, sigaction_basic); 147 ATF_TP_ADD_TC(tp, sigaction_noflags); 148 ATF_TP_ADD_TC(tp, sigaction_resethand); 149 150 return atf_no_error(); 151 } 152