1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 * IN THE SOFTWARE.
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <dlfcn.h>
26 #include <algorithm.h>
27 #include <fstream>
28 #include <iostream>
29 #include <unistd.h>
30 #include <sys/mman.h>
31 #include <gtest/gtest.h>
32
33 #include <signal.h>
34 #include <sigchain.h>
35
36 #define SIGNAL_CHAIN_SPECIAL_ACTION_MAX 3
37
38 extern "C"{
39 bool intercept_sigchain(int signo, const struct sigaction *__restrict sa, struct sigaction *__restrict old);
40 int sigchain_sigmask(int how, const sigset_t *__restrict set, sigset_t *__restrict old);
41 void add_special_handler_at_last(int signo, struct signal_chain_action* sa);
42 }
43
44 using namespace testing::ext;
45 using namespace std;
46
47 namespace OHOS {
48 namespace {
49
50 class SigchainTest : public testing::Test {
51 public:
52 static void TearDownTestCase(void);
53 };
54
TearDownTestCase(void)55 void SigchainTest::TearDownTestCase(void)
56 {
57 }
58
59 // The special handler
sigaction_special_handler(int signo,siginfo_t * siginfo,void * ucontext_raw)60 static bool sigaction_special_handler(int signo, siginfo_t *siginfo, void *ucontext_raw)
61 {
62 return false;
63 }
64
65 /**
66 *@tc.name: sigchain_sigmask_test_001
67 *@tc.desc: Test the add_special_handler_at_last function. When the input how - SIG_BLOCK > 2U , the expectation is EINVAL.
68 *@tc.type: FUNC
69 */
70 HWTEST_F(SigchainTest, sigchain_sigmask_test_001, TestSize.Level0)
71 {
72 sigset_t set;
73 int res = sigaction_sigmask(10, &set, NULL);
74 EXPECT_TRUE(res == EINVAL);
75 }
76
77 /**
78 *@tc.name: sigchain_sigmask_test_002
79 *@tc.desc: Test the add_special_handler_at_last function. When the input set is NULL, the expectation is EINVAL.
80 *@tc.type: FUNC
81 */
82 HWTEST_F(SigchainTest, sigchain_sigmask_test_002, TestSize.Level0)
83 {
84 int res = sigaction_sigmask(10, NULL, NULL);
85 EXPECT_TRUE(res == EINVAL);
86 }
87
88 /**
89 *@tc.name: sigchain_add_special_handler_at_last_test_001
90 *@tc.desc: Test the add_special_handler_at_last function. When the input signo is
91 out of range (0, _NSIG), the expectation is abort.
92 *@tc.type: FUNC
93 */
94 HWTEST_F(SigchainTest, sigchain_add_special_handler_at_last_test_001, TestSize.Level0)
95 {
96 struct signal_chain_action mock_sa = {
97 .sca_sigaction = sigaction_special_handler,
98 .sca_mask = {};
99 .sca_flags = 0;
100 };
101 EXPECT_DEATH(add_special_handler_at_last(-1, &mock_sa), ".*");
102 EXPECT_DEATH(add_special_handler_at_last(_NSIG, &mock_sa), ".*");
103 }
104
105 /**
106 *@tc.name: sigchain_add_special_handler_at_last_test_002
107 *@tc.desc: Test the add_special_handler_at_last function. When adding more than one
108 signal_chain_action to the same signal, the expectation is abort.
109 *@tc.type: FUNC
110 */
111 HWTEST_F(SigchainTest, sigchain_add_special_handler_at_last_test_002, TestSize.Level0)
112 {
113 remove_all_special_handler(45);
114 struct signal_chain_action mock_sa = {
115 .sca_sigaction = sigaction_special_handler,
116 .sca_mask = {};
117 .sca_flags = 0;
118 };
119 add_special_handler_at_last(45, &mock_sa);
120 EXPECT_DEATH(add_special_handler_at_last(45, &mock_sa), ".*");
121 remove_all_special_handler(45);
122 }
123
124 /**
125 *@tc.name: sigchain_add_special_signal_handler_test_001
126 *@tc.desc: Test the add_special_handler function. When the input signo is
127 out of range (0, _NSIG), the expectation is abort.
128 *@tc.type: FUNC
129 */
130 HWTEST_F(SigchainTest, sigchain_add_special_signal_handler_test_001, TestSize.Level0)
131 {
132 struct signal_chain_action mock_sa = {
133 .sca_sigaction = sigaction_special_handler,
134 .sca_mask = {};
135 .sca_flags = 0;
136 };
137 EXPECT_DEATH(add_special_signal_handler(-1, &mock_sa), ".*");
138 EXPECT_DEATH(add_special_signal_handler(_NSIG, &mock_sa), ".*");
139 }
140
141 /**
142 *@tc.name: sigchain_add_special_signal_handler_test_002
143 *@tc.desc: Test the add_special_handler function by add_special_handler.
144 When adding more max number of special special actions to a signal,
145 the expectation is abort.
146 *@tc.type: FUNC
147 */
148 HWTEST_F(SigchainTest, sigchain_add_special_signal_handler_test_002, TestSize.Level0)
149 {
150 remove_all_special_handler(45);
151 struct signal_chain_action mock_sa = {
152 .sca_sigaction = sigaction_special_handler,
153 .sca_mask = {};
154 .sca_flags = 0;
155 };
156 for (int i = 0; i < SIGNAL_CHAIN_SPECIAL_ACTION_MAX; i++) {
157 add_special_signal_handler(45, &mock_sa);
158 }
159 EXPECT_DEATH(add_special_signal_handler(45, &mock_sa), ".*");
160 remove_all_special_handler(45);
161 }
162
163 /**
164 *@tc.name: sigchain_remove_special_signal_handler_test_001
165 *@tc.desc: Test the remove_special_signal_handler function. When the input signo is
166 out of range (0, _NSIG), the expectation is abort.
167 *@tc.type: FUNC
168 */
169 HWTEST_F(SigchainTest, sigchain_remove_special_signal_handler_test_001, TestSize.Level0)
170 {
171 EXPECT_DEATH(remove_special_signal_handler(-1, sigchain_special_handler), ".*");
172 EXPECT_DEATH(remove_special_signal_handler(_NSIG, sigchain_special_handler), ".*");
173 }
174
175 /**
176 *@tc.name: sigchain_remove_special_signal_handler_test_002
177 *@tc.desc: Test the remove_special_signal_handler function. When removing
178 a signal which is not marked(special action list is empty),
179 nothing happen.
180 *@tc.type: FUNC
181 */
182 HWTEST_F(SigchainTest, sigchain_remove_special_signal_handler_test_002, TestSize.Level0)
183 {
184 remove_all_special_handler(45);
185 remove_special_signal_handler(45, sigchain_special_handler);
186 }
187
188 /**
189 *@tc.name: sigchain_remove_all_special_handler_test_001
190 *@tc.desc: Test the remove_all_special_handler function. When the input signo is
191 out of range (0, _NSIG), the expectation is abort.
192 *@tc.type: FUNC
193 */
194 HWTEST_F(SigchainTest, sigchain_remove_all_special_handler_test_001, TestSize.Level0)
195 {
196 EXPECT_DEATH(remove_all_special_handler(-1), ".*");
197 EXPECT_DEATH(remove_all_special_handler(_NSIG), ".*");
198 }
199
200 /**
201 *@tc.name: sigchain_remove_all_special_handler_test_002
202 *@tc.desc: Test the remove_all_special_handler function. When removing
203 a signal which is not marked(special action list is empty)
204 *@tc.type: FUNC
205 */
206 HWTEST_F(SigchainTest, sigchain_remove_all_special_handler_test_002, TestSize.Level0)
207 {
208 remove_all_special_handler(45);
209 remove_all_special_handler(45);
210 }
211
212 /**
213 *@tc.name: intercept_sigaction_test_001
214 *@tc.desc: Test the intercept_sigaction function. When the input signo is
215 out of range (0, _NSIG), the result is false.
216 *@tc.type: FUNC
217 */
218 HWTEST_F(SigchainTest, intercept_sigaction_test_001, TestSize.Level0)
219 {
220 struct sigaction sa, old;
221 bool res = intercept_sigaction(-1, &sa, &old);
222 ASSERT_TRUE(res == false);
223 }
224
225 /**
226 *@tc.name: intercept_sigaction_test_002
227 *@tc.desc: Test the intercept_sigaction function. When the input signo is
228 out of range(0, _NSIG), the result is false.
229 *@tc.type: FUNC
230 */
231 HWTEST_F(SigchainTest, intercept_sigaction_test_002, TestSize.Level0)
232 {
233 struct sigaction sa, old;
234 bool res = intercept_sigaction(_NSIG, &sa, &old);
235 ASSERT_TRUE(res == false);
236 }
237
238 } //namespace
239 } //namespace OHOS