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