• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <signal.h>
17 #include <errno.h>
18 #include <string.h>
19 #include "stdbool.h"
20 #include "syscall.h"
21 #include "pthread_impl.h"
22 #include "libc.h"
23 #include "lock.h"
24 #include "ksigaction.h"
25 
26 #define DEFAULT_SIG_NUM 64
27 #define SIGNO2SET(s)            ((sigset_t)1 << (s))
28 #define NULL_SIGNAL_SET         ((sigset_t)0x00000000)
29 #define SET_BIT(bitmap, pos)    (bitmap |= (1u << pos))
30 #define CLEAR_BIT(bitmap, pos)  (bitmap &= ~(1u << pos))
31 #define CHECK_BIT(bitmap, pos)  ((bitmap & (1u << pos)) ? 1 : 0)
32 #define SIG_FLAG_NOIGNORE 1
33 
34 struct sigactq {
35 	struct sigaction act;
36 	bool	ign_flag;
37 	unsigned char   signo;
38 	unsigned char   sigmask;
39 	unsigned char   reserve[2];
40 };
41 typedef struct sigactq sigactq_t;
42 
43 typedef void (*sa_sighandler_t)(int);
44 typedef struct sigaction sigaction_t;
45 
46 static sigactq_t g_sig_arr[DEFAULT_SIG_NUM];
47 static pthread_spinlock_t sig_lite_lock;
48 
49 struct sig_default_act {
50 	unsigned char singNo;
51 	unsigned char flag;
52 	sa_sighandler_t action;
53 };
54 
55 static void __sig_core(int signo);
56 static void __sig_kill(int signo);
57 static void __sig_cont(int signo);
58 static void __sig_stop(int signo);
59 static void __sig_ignore(int signo);
60 static const struct sig_default_act sig_default_action[] = {
61 	{SIGHUP, 0, __sig_kill},
62 	{SIGINT, 0, __sig_kill},
63 	{SIGQUIT, 0, __sig_core},
64 	{SIGILL, 0, __sig_core},
65 	{SIGTRAP, 0, __sig_core},
66 	{SIGABRT, 0, __sig_core},
67 	{SIGBUS, 0, __sig_core},
68 	{SIGFPE, 0, __sig_core},
69 	{SIGKILL, SIG_FLAG_NOIGNORE, __sig_kill},
70 	{SIGUSR1, 0, __sig_kill},
71 	{SIGSEGV, 0, __sig_core},
72 	{SIGUSR2, 0, __sig_kill},
73 	{SIGPIPE, 0, __sig_kill},
74 	{SIGALRM, 0, __sig_kill},
75 	{SIGTERM, 0, __sig_kill},
76 	{SIGSTKFLT, 0, __sig_kill},
77 	{SIGCHLD, 0, __sig_ignore},
78 	{SIGCONT, SIG_FLAG_NOIGNORE, __sig_cont},
79 	{SIGSTOP, SIG_FLAG_NOIGNORE, __sig_stop},
80 	{SIGTSTP, 0, __sig_stop},
81 	{SIGTTIN, 0, __sig_stop},
82 	{SIGTTOU, 0, __sig_stop},
83 	{SIGURG, 0, __sig_ignore},
84 	{SIGXCPU, 0, __sig_core},
85 	{SIGXFSZ, 0, __sig_core},
86 	{SIGVTALRM, 0, __sig_kill},
87 	{SIGPROF, 0, __sig_kill},
88 	{SIGWINCH, 0, __sig_ignore},
89 	{SIGIO, 0, __sig_kill},
90 	{SIGPWR, 0, __sig_kill},
91 	{SIGSYS, 0, __sig_ignore},
92 	{32, 0, __sig_ignore},
93 	{33, 0, __sig_ignore},
94 	{34, 0, __sig_ignore},
95 	{35, 0, __sig_ignore},
96 	{36, 0, __sig_ignore},
97 	{37, 0, __sig_ignore},
98 	{38, 0, __sig_ignore},
99 	{39, 0, __sig_ignore},
100 	{40, 0, __sig_ignore},
101 	{41, 0, __sig_ignore},
102 	{42, 0, __sig_ignore},
103 	{43, 0, __sig_ignore},
104 	{44, 0, __sig_ignore},
105 	{45, 0, __sig_ignore},
106 	{46, 0, __sig_ignore},
107 	{47, 0, __sig_ignore},
108 	{48, 0, __sig_ignore},
109 	{49, 0, __sig_ignore},
110 	{50, 0, __sig_ignore},
111 	{51, 0, __sig_ignore},
112 	{52, 0, __sig_ignore},
113 	{53, 0, __sig_ignore},
114 	{54, 0, __sig_ignore},
115 	{55, 0, __sig_ignore},
116 	{56, 0, __sig_ignore},
117 	{57, 0, __sig_ignore},
118 	{58, 0, __sig_ignore},
119 	{59, 0, __sig_ignore},
120 	{60, 0, __sig_ignore},
121 	{61, 0, __sig_ignore},
122 	{62, 0, __sig_ignore},
123 	{63, 0, __sig_ignore},
124 	{64, 0, __sig_ignore},
125 };
126 
__sig_core(int signo)127 static void __sig_core(int signo)
128 {
129 	exit(-1);
130 }
131 
__sig_kill(int signo)132 static void __sig_kill(int signo)
133 {
134 	exit(-1);
135 }
136 
__sig_cont(int signo)137 static void __sig_cont(int signo)
138 {
139 	return;
140 }
141 
__sig_stop(int signo)142 static void __sig_stop(int signo)
143 {
144     return;
145 }
146 
__sig_ignore(int signo)147 static void __sig_ignore(int signo)
148 {
149     return;
150 }
151 
__sig_find_action(int sig)152 static sigactq_t *__sig_find_action(int sig)
153 {
154 	int i;
155 
156 	for (i = 0; i < sizeof(sig_default_action) / sizeof(struct sig_default_act); i++) {
157 		if (g_sig_arr[i].signo == sig) {
158 			return (g_sig_arr + i);
159 		}
160 	}
161 }
162 
__sig_copy_sigaction(sigaction_t * src,sigaction_t * dst)163 static void __sig_copy_sigaction(sigaction_t *src, sigaction_t *dst)
164 {
165 	dst->sa_handler = src->sa_handler;
166 	dst->sa_mask = src->sa_mask;
167 	dst->sa_flags = src->sa_flags;
168 }
169 
__sig_cannot_catche(int sig,sa_sighandler_t handler)170 static int __sig_cannot_catche(int sig, sa_sighandler_t handler)
171 {
172 	int i;
173 
174 	for (i = 0; i < sizeof(sig_default_action) / sizeof(struct sig_default_act); i++) {
175 		if (sig == sig_default_action[i].singNo) {
176 			return (sig_default_action[i].flag == SIG_FLAG_NOIGNORE) && (handler != SIG_DFL);
177 		}
178 	}
179 	/* This sig can be catch and ignore return false */
180 	return 0;
181 }
182 
__sig_operation(unsigned int receivedSigno)183 static void __sig_operation(unsigned int receivedSigno)
184 {
185 	int i;
186 	sigset_t mask, oldmask;
187 
188 	sigemptyset(&mask);
189 	sigemptyset(&oldmask);
190 
191 	for (i = 0; i < sizeof(sig_default_action) / sizeof(struct sig_default_act); i++) {
192 		if (!g_sig_arr[i].ign_flag && g_sig_arr[i].signo == receivedSigno && g_sig_arr[i].act.sa_handler) {
193 			sigaddset(&mask, receivedSigno);
194 			sigprocmask(SIG_BLOCK, &mask, &oldmask);
195 			sigprocmask(SIG_BLOCK, &g_sig_arr[i].act.sa_mask, NULL);
196 			(*g_sig_arr[i].act.sa_handler)(g_sig_arr[i].signo);
197 			sigprocmask(SIG_SETMASK, &oldmask, NULL);
198 			return;
199 		}
200 	}
201 }
202 
arm_signal_process(unsigned int receivedSig)203 void arm_signal_process(unsigned int receivedSig)
204 {
205 	__sig_operation(receivedSig);
206 }
207 
__sig_add_def_action()208 static void __sig_add_def_action()
209 {
210 	int i;
211 
212 	for (i = 0; i < sizeof(sig_default_action) / sizeof(struct sig_default_act); i++) {
213 		g_sig_arr[i].signo = (unsigned char)sig_default_action[i].singNo;
214 		g_sig_arr[i].act.sa_handler = sig_default_action[i].action;
215 		sigemptyset(&g_sig_arr[i].act.sa_mask);
216 		g_sig_arr[i].act.sa_flags = sig_default_action[i].flag;
217 		g_sig_arr[i].ign_flag = false;
218 	}
219 }
220 
__sig_find_def_action(unsigned char signo)221 static sa_sighandler_t __sig_find_def_action(unsigned char signo)
222 {
223 	int i;
224 
225 	for (i = 0; i < sizeof(sig_default_action) / sizeof(struct sig_default_act); i++) {
226 		if (signo == sig_default_action[i].singNo) {
227 			return sig_default_action[i].action;
228 		}
229 	}
230 	return NULL;
231 }
232 
__sig_dfl_opr(int sig,sigactq_t * sigact,const sigaction_t * act)233 static int __sig_dfl_opr(int sig, sigactq_t *sigact, const sigaction_t *act)
234 {
235 	sa_sighandler_t def_handler = NULL;
236 
237 	def_handler = __sig_find_def_action(sig);
238 
239 	if (def_handler != NULL) {
240 		/* Replace it from signal action queue */
241 		sigact->act.sa_handler = def_handler;
242 		sigact->act.sa_mask = act->sa_mask;
243 		sigact->act.sa_flags = act->sa_flags;
244 	}
245 	return 0;
246 }
247 
__sig_action_opr(int sig,const sigaction_t * act,sigaction_t * oact)248 static int __sig_action_opr(int sig, const sigaction_t *act, sigaction_t *oact)
249 {
250 	int ret = 0;
251 	sa_sighandler_t handler = NULL;
252 	sigactq_t *sigact = NULL;
253 
254 	if (act == NULL) return -EINVAL;
255 
256 	if (sig < SIGHUP || sig > (_NSIG - 1)) return -EINVAL;
257 
258 	handler = act->sa_handler;
259 	/* Skip sig that can not be catched */
260 	if (__sig_cannot_catche(sig, handler)) return -EINVAL;
261 
262 	pthread_spin_lock(&sig_lite_lock);
263 	sigact = __sig_find_action(sig);
264 	if (sigact && oact) __sig_copy_sigaction(&sigact->act, oact);
265 
266 	sigact->ign_flag = false;
267 
268 	if (handler == SIG_IGN && sigact) {
269 		sigact->ign_flag = true;
270 	} else if (handler == SIG_DFL) {
271 		ret = __sig_dfl_opr(sig, sigact, act);
272 	} else {
273 		sigact->act.sa_handler = handler;
274 		sigact->act.sa_mask = act->sa_mask;
275 		sigact->act.sa_flags = act->sa_flags;
276 	}
277 
278 	pthread_spin_unlock(&sig_lite_lock);
279 	return ret;
280 }
281 
__sig_init(void)282 void __sig_init(void)
283 {
284 	signal(SIGSYS, arm_do_signal);
285 	pthread_spin_init(&sig_lite_lock, 0);
286 	__sig_add_def_action();
287 }
288 
289 static int unmask_done;
290 static unsigned long handler_set[_NSIG / (8 * sizeof(long))];
291 
__get_handler_set(sigset_t * set)292 void __get_handler_set(sigset_t *set)
293 {
294 	memcpy(set, handler_set, sizeof handler_set);
295 }
296 
297 volatile int __eintr_valid_flag;
298 
__libc_sigaction(int sig,const struct sigaction * restrict sa,struct sigaction * restrict old)299 int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
300 {
301 	sigaction_t ksa, ksa_old;
302 	int r = 0;
303 
304 	if (sa) {
305 		if ((uintptr_t)sa->sa_handler > 1UL) {
306 			a_or_l(handler_set + (sig - 1) / (8 * sizeof(long)),
307 				1UL<<(sig - 1) % (8 * sizeof(long)));
308 
309 			/* If pthread_create has not yet been called,
310 			 * implementation-internal signals might not
311 			 * yet have been unblocked. They must be
312 			 * unblocked before any signal handler is
313 			 * installed, so that an application cannot
314 			 * receive an illegal sigset_t (with them
315 			 * blocked) as part of the ucontext_t passed
316 			 * to the signal handler. */
317 			if (!libc.threaded && !unmask_done) {
318 				__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
319 					SIGPT_SET, 0, _NSIG/8);
320 				unmask_done = 1;
321 			}
322 
323 			if (!(sa->sa_flags & SA_RESTART)) {
324 				a_store(&__eintr_valid_flag, 1);
325 			}
326 		}
327 		ksa.sa_handler = sa->sa_handler;
328 		ksa.sa_flags = sa->sa_flags;
329 #ifdef SA_RESTORER
330 		ksa.sa_flags |= SA_RESTORER;
331 		ksa.sa_restorer = (sa->sa_flags & SA_SIGINFO) ? __restore_rt : __restore;
332 #endif
333 		memcpy(&ksa.sa_mask, &sa->sa_mask, _NSIG / 8);
334 	}
335 
336 	if (sig == SIGSYS) {
337 		return syscall(SYS_rt_sigaction, sig, sa ? &ksa : 0, old?&ksa_old:0, _NSIG / 8);
338 	} else {
339 		r = __sig_action_opr(sig, (const sigaction_t*)sa ? &ksa : 0, (sigaction_t*)old?&ksa_old:0);
340 	}
341 	if (old && !r) {
342 		old->sa_handler = ksa_old.sa_handler;
343 		old->sa_flags = ksa_old.sa_flags;
344 		memcpy(&old->sa_mask, &ksa_old.sa_mask, _NSIG / 8);
345 	}
346 	return __syscall_ret(r);
347 }
348 
__sigaction(int sig,const struct sigaction * restrict sa,struct sigaction * restrict old)349 int __sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
350 {
351 	unsigned long set[_NSIG/(8*sizeof(long))];
352 
353 	if (sig-32U < 3 || sig-1U >= _NSIG-1) {
354 		errno = EINVAL;
355 		return -1;
356 	}
357 
358 	/* Doing anything with the disposition of SIGABRT requires a lock,
359 	 * so that it cannot be changed while abort is terminating the
360 	 * process and so any change made by abort can't be observed. */
361 	if (sig == SIGABRT) {
362 		__block_all_sigs(&set);
363 		LOCK(__abort_lock);
364 	}
365 	int r = __libc_sigaction(sig, sa, old);
366 	if (sig == SIGABRT) {
367 		UNLOCK(__abort_lock);
368 		__restore_sigs(&set);
369 	}
370 	return r;
371 }
372 
373 weak_alias(__sigaction, sigaction);
374