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 <cstdio>
24 #include <cstdlib>
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 <csignal>
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.
68 When the input how - SIG_BLOCK > 2U , the expectation is EINVAL.
69 *@tc.type: FUNC
70 */
71 HWTEST_F(SigchainTest, sigchain_sigmask_test_001, TestSize.Level0)
72 {
73 sigset_t set;
74 int res = sigaction_sigmask(10, &set, NULL);
75 EXPECT_TRUE(res == EINVAL);
76 }
77
78 /**
79 *@tc.name: sigchain_sigmask_test_002
80 *@tc.desc: Test the add_special_handler_at_last function. When the input set is NULL, the expectation is EINVAL.
81 *@tc.type: FUNC
82 */
83 HWTEST_F(SigchainTest, sigchain_sigmask_test_002, TestSize.Level0)
84 {
85 int res = sigaction_sigmask(10, NULL, NULL);
86 EXPECT_TRUE(res == EINVAL);
87 }
88
89 /**
90 *@tc.name: sigchain_add_special_handler_at_last_test_001
91 *@tc.desc: Test the add_special_handler_at_last function. When the input signo is
92 out of range (0, _NSIG), the expectation is abort.
93 *@tc.type: FUNC
94 */
95 HWTEST_F(SigchainTest, sigchain_add_special_handler_at_last_test_001, TestSize.Level0)
96 {
97 struct signal_chain_action mock_sa = {
98 .sca_sigaction = sigaction_special_handler,
99 .sca_mask = {};
100 .sca_flags = 0;
101 };
102 EXPECT_DEATH(add_special_handler_at_last(-1, &mock_sa), ".*");
103 EXPECT_DEATH(add_special_handler_at_last(_NSIG, &mock_sa), ".*");
104 }
105
106 /**
107 *@tc.name: sigchain_add_special_handler_at_last_test_002
108 *@tc.desc: Test the add_special_handler_at_last function. When adding more than one
109 signal_chain_action to the same signal, the expectation is abort.
110 *@tc.type: FUNC
111 */
112 HWTEST_F(SigchainTest, sigchain_add_special_handler_at_last_test_002, TestSize.Level0)
113 {
114 remove_all_special_handler(45);
115 struct signal_chain_action mock_sa = {
116 .sca_sigaction = sigaction_special_handler,
117 .sca_mask = {};
118 .sca_flags = 0;
119 };
120 add_special_handler_at_last(45, &mock_sa);
121 EXPECT_DEATH(add_special_handler_at_last(45, &mock_sa), ".*");
122 remove_all_special_handler(45);
123 }
124
125 /**
126 *@tc.name: sigchain_add_special_signal_handler_test_001
127 *@tc.desc: Test the add_special_handler function. When the input signo is
128 out of range (0, _NSIG), the expectation is abort.
129 *@tc.type: FUNC
130 */
131 HWTEST_F(SigchainTest, sigchain_add_special_signal_handler_test_001, TestSize.Level0)
132 {
133 struct signal_chain_action mock_sa = {
134 .sca_sigaction = sigaction_special_handler,
135 .sca_mask = {};
136 .sca_flags = 0;
137 };
138 EXPECT_DEATH(add_special_signal_handler(-1, &mock_sa), ".*");
139 EXPECT_DEATH(add_special_signal_handler(_NSIG, &mock_sa), ".*");
140 }
141
142 /**
143 *@tc.name: sigchain_add_special_signal_handler_test_002
144 *@tc.desc: Test the add_special_handler function by add_special_handler.
145 When adding more max number of special special actions to a signal,
146 the expectation is abort.
147 *@tc.type: FUNC
148 */
149 HWTEST_F(SigchainTest, sigchain_add_special_signal_handler_test_002, TestSize.Level0)
150 {
151 remove_all_special_handler(45);
152 struct signal_chain_action mock_sa = {
153 .sca_sigaction = sigaction_special_handler,
154 .sca_mask = {};
155 .sca_flags = 0;
156 };
157 for (int i = 0; i < SIGNAL_CHAIN_SPECIAL_ACTION_MAX; i++) {
158 add_special_signal_handler(45, &mock_sa);
159 }
160 EXPECT_DEATH(add_special_signal_handler(45, &mock_sa), ".*");
161 remove_all_special_handler(45);
162 }
163
164 /**
165 *@tc.name: sigchain_remove_special_signal_handler_test_001
166 *@tc.desc: Test the remove_special_signal_handler function. When the input signo is
167 out of range (0, _NSIG), the expectation is abort.
168 *@tc.type: FUNC
169 */
170 HWTEST_F(SigchainTest, sigchain_remove_special_signal_handler_test_001, TestSize.Level0)
171 {
172 EXPECT_DEATH(remove_special_signal_handler(-1, sigchain_special_handler), ".*");
173 EXPECT_DEATH(remove_special_signal_handler(_NSIG, sigchain_special_handler), ".*");
174 }
175
176 /**
177 *@tc.name: sigchain_remove_special_signal_handler_test_002
178 *@tc.desc: Test the remove_special_signal_handler function. When removing
179 a signal which is not marked(special action list is empty),
180 nothing happen.
181 *@tc.type: FUNC
182 */
183 HWTEST_F(SigchainTest, sigchain_remove_special_signal_handler_test_002, TestSize.Level0)
184 {
185 remove_all_special_handler(45);
186 remove_special_signal_handler(45, sigchain_special_handler);
187 }
188
189 /**
190 *@tc.name: sigchain_remove_all_special_handler_test_001
191 *@tc.desc: Test the remove_all_special_handler function. When the input signo is
192 out of range (0, _NSIG), the expectation is abort.
193 *@tc.type: FUNC
194 */
195 HWTEST_F(SigchainTest, sigchain_remove_all_special_handler_test_001, TestSize.Level0)
196 {
197 EXPECT_DEATH(remove_all_special_handler(-1), ".*");
198 EXPECT_DEATH(remove_all_special_handler(_NSIG), ".*");
199 }
200
201 /**
202 *@tc.name: sigchain_remove_all_special_handler_test_002
203 *@tc.desc: Test the remove_all_special_handler function. When removing
204 a signal which is not marked(special action list is empty)
205 *@tc.type: FUNC
206 */
207 HWTEST_F(SigchainTest, sigchain_remove_all_special_handler_test_002, TestSize.Level0)
208 {
209 remove_all_special_handler(45);
210 remove_all_special_handler(45);
211 }
212
213 /**
214 *@tc.name: intercept_sigaction_test_001
215 *@tc.desc: Test the intercept_sigaction function. When the input signo is
216 out of range (0, _NSIG), the result is false.
217 *@tc.type: FUNC
218 */
219 HWTEST_F(SigchainTest, intercept_sigaction_test_001, TestSize.Level0)
220 {
221 struct sigaction sa, old;
222 bool res = intercept_sigaction(-1, &sa, &old);
223 ASSERT_TRUE(res == false);
224 }
225
226 /**
227 *@tc.name: intercept_sigaction_test_002
228 *@tc.desc: Test the intercept_sigaction function. When the input signo is
229 out of range(0, _NSIG), the result is false.
230 *@tc.type: FUNC
231 */
232 HWTEST_F(SigchainTest, intercept_sigaction_test_002, TestSize.Level0)
233 {
234 struct sigaction sa, old;
235 bool res = intercept_sigaction(_NSIG, &sa, &old);
236 ASSERT_TRUE(res == false);
237 }
238
239 } //namespace
240 } //namespace OHOS