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 34struct sigactq { 35 struct sigaction act; 36 bool ign_flag; 37 unsigned char signo; 38 unsigned char sigmask; 39 unsigned char reserve[2]; 40}; 41typedef struct sigactq sigactq_t; 42 43typedef void (*sa_sighandler_t)(int); 44typedef struct sigaction sigaction_t; 45 46static sigactq_t g_sig_arr[DEFAULT_SIG_NUM]; 47static pthread_spinlock_t sig_lite_lock; 48 49struct sig_default_act { 50 unsigned char singNo; 51 unsigned char flag; 52 sa_sighandler_t action; 53}; 54 55static void __sig_core(int signo); 56static void __sig_kill(int signo); 57static void __sig_cont(int signo); 58static void __sig_stop(int signo); 59static void __sig_ignore(int signo); 60static 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 127static void __sig_core(int signo) 128{ 129 exit(-1); 130} 131 132static void __sig_kill(int signo) 133{ 134 exit(-1); 135} 136 137static void __sig_cont(int signo) 138{ 139 return; 140} 141 142static void __sig_stop(int signo) 143{ 144 return; 145} 146 147static void __sig_ignore(int signo) 148{ 149 return; 150} 151 152static 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 163static 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 170static 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 183static 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 203void arm_signal_process(unsigned int receivedSig) 204{ 205 __sig_operation(receivedSig); 206} 207 208static 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 221static 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 233static 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 248static 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 282void __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 289static int unmask_done; 290static unsigned long handler_set[_NSIG / (8 * sizeof(long))]; 291 292void __get_handler_set(sigset_t *set) 293{ 294 memcpy(set, handler_set, sizeof handler_set); 295} 296 297volatile int __eintr_valid_flag; 298 299int __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 349int __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 373weak_alias(__sigaction, sigaction); 374