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