1*db70f181Schristos /* $NetBSD: sys_sig.c,v 1.45 2015/10/02 16:54:15 christos Exp $ */ 2b07ec3fcSad 3b07ec3fcSad /*- 4284c2b9aSad * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. 5b07ec3fcSad * All rights reserved. 6b07ec3fcSad * 7b07ec3fcSad * This code is derived from software contributed to The NetBSD Foundation 8b07ec3fcSad * by Andrew Doran. 9b07ec3fcSad * 10b07ec3fcSad * Redistribution and use in source and binary forms, with or without 11b07ec3fcSad * modification, are permitted provided that the following conditions 12b07ec3fcSad * are met: 13b07ec3fcSad * 1. Redistributions of source code must retain the above copyright 14b07ec3fcSad * notice, this list of conditions and the following disclaimer. 15b07ec3fcSad * 2. Redistributions in binary form must reproduce the above copyright 16b07ec3fcSad * notice, this list of conditions and the following disclaimer in the 17b07ec3fcSad * documentation and/or other materials provided with the distribution. 18b07ec3fcSad * 19b07ec3fcSad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20b07ec3fcSad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21b07ec3fcSad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22b07ec3fcSad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23b07ec3fcSad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24b07ec3fcSad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25b07ec3fcSad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26b07ec3fcSad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27b07ec3fcSad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28b07ec3fcSad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29b07ec3fcSad * POSSIBILITY OF SUCH DAMAGE. 30b07ec3fcSad */ 31b07ec3fcSad 32b07ec3fcSad /* 33b07ec3fcSad * Copyright (c) 1982, 1986, 1989, 1991, 1993 34b07ec3fcSad * The Regents of the University of California. All rights reserved. 35b07ec3fcSad * (c) UNIX System Laboratories, Inc. 36b07ec3fcSad * All or some portions of this file are derived from material licensed 37b07ec3fcSad * to the University of California by American Telephone and Telegraph 38b07ec3fcSad * Co. or Unix System Laboratories, Inc. and are reproduced herein with 39b07ec3fcSad * the permission of UNIX System Laboratories, Inc. 40b07ec3fcSad * 41b07ec3fcSad * Redistribution and use in source and binary forms, with or without 42b07ec3fcSad * modification, are permitted provided that the following conditions 43b07ec3fcSad * are met: 44b07ec3fcSad * 1. Redistributions of source code must retain the above copyright 45b07ec3fcSad * notice, this list of conditions and the following disclaimer. 46b07ec3fcSad * 2. Redistributions in binary form must reproduce the above copyright 47b07ec3fcSad * notice, this list of conditions and the following disclaimer in the 48b07ec3fcSad * documentation and/or other materials provided with the distribution. 49b07ec3fcSad * 3. Neither the name of the University nor the names of its contributors 50b07ec3fcSad * may be used to endorse or promote products derived from this software 51b07ec3fcSad * without specific prior written permission. 52b07ec3fcSad * 53b07ec3fcSad * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54b07ec3fcSad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55b07ec3fcSad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56b07ec3fcSad * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57b07ec3fcSad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58b07ec3fcSad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59b07ec3fcSad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60b07ec3fcSad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61b07ec3fcSad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62b07ec3fcSad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63b07ec3fcSad * SUCH DAMAGE. 64b07ec3fcSad * 65b07ec3fcSad * @(#)kern_sig.c 8.14 (Berkeley) 5/14/95 66b07ec3fcSad */ 67b07ec3fcSad 68b07ec3fcSad #include <sys/cdefs.h> 69*db70f181Schristos __KERNEL_RCSID(0, "$NetBSD: sys_sig.c,v 1.45 2015/10/02 16:54:15 christos Exp $"); 70*db70f181Schristos 71*db70f181Schristos #include "opt_dtrace.h" 72b07ec3fcSad 73b07ec3fcSad #include <sys/param.h> 74b07ec3fcSad #include <sys/kernel.h> 75b07ec3fcSad #include <sys/signalvar.h> 76b07ec3fcSad #include <sys/proc.h> 77b07ec3fcSad #include <sys/pool.h> 78b07ec3fcSad #include <sys/syscallargs.h> 79b07ec3fcSad #include <sys/kauth.h> 80b07ec3fcSad #include <sys/wait.h> 81b07ec3fcSad #include <sys/kmem.h> 8292ce8c6aSad #include <sys/module.h> 83*db70f181Schristos #include <sys/sdt.h> 84*db70f181Schristos 85*db70f181Schristos SDT_PROVIDER_DECLARE(proc); 86*db70f181Schristos SDT_PROBE_DEFINE2(proc, kernel, , signal__clear, 87*db70f181Schristos "int", /* signal */ 88*db70f181Schristos "ksiginfo_t *"); /* signal-info */ 89b07ec3fcSad 90b07ec3fcSad int 913c74cdf1Srmind sys___sigaction_sigtramp(struct lwp *l, 923c74cdf1Srmind const struct sys___sigaction_sigtramp_args *uap, register_t *retval) 93b07ec3fcSad { 947e2790cfSdsl /* { 95b07ec3fcSad syscallarg(int) signum; 96b07ec3fcSad syscallarg(const struct sigaction *) nsa; 97b07ec3fcSad syscallarg(struct sigaction *) osa; 98b07ec3fcSad syscallarg(void *) tramp; 99b07ec3fcSad syscallarg(int) vers; 1007e2790cfSdsl } */ 101b07ec3fcSad struct sigaction nsa, osa; 102b07ec3fcSad int error; 103b07ec3fcSad 104b07ec3fcSad if (SCARG(uap, nsa)) { 105b07ec3fcSad error = copyin(SCARG(uap, nsa), &nsa, sizeof(nsa)); 106b07ec3fcSad if (error) 107b07ec3fcSad return (error); 108b07ec3fcSad } 109b07ec3fcSad error = sigaction1(l, SCARG(uap, signum), 110b07ec3fcSad SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0, 111b07ec3fcSad SCARG(uap, tramp), SCARG(uap, vers)); 112b07ec3fcSad if (error) 113b07ec3fcSad return (error); 114b07ec3fcSad if (SCARG(uap, osa)) { 115b07ec3fcSad error = copyout(&osa, SCARG(uap, osa), sizeof(osa)); 116b07ec3fcSad if (error) 117b07ec3fcSad return (error); 118b07ec3fcSad } 1193c74cdf1Srmind return 0; 120b07ec3fcSad } 121b07ec3fcSad 122b07ec3fcSad /* 123b07ec3fcSad * Manipulate signal mask. Note that we receive new mask, not pointer, and 124b07ec3fcSad * return old mask as return value; the library stub does the rest. 125b07ec3fcSad */ 126b07ec3fcSad int 1273c74cdf1Srmind sys___sigprocmask14(struct lwp *l, const struct sys___sigprocmask14_args *uap, 1283c74cdf1Srmind register_t *retval) 129b07ec3fcSad { 1307e2790cfSdsl /* { 131b07ec3fcSad syscallarg(int) how; 132b07ec3fcSad syscallarg(const sigset_t *) set; 133b07ec3fcSad syscallarg(sigset_t *) oset; 1347e2790cfSdsl } */ 135b07ec3fcSad struct proc *p = l->l_proc; 136b07ec3fcSad sigset_t nss, oss; 137b07ec3fcSad int error; 138b07ec3fcSad 139b07ec3fcSad if (SCARG(uap, set)) { 140b07ec3fcSad error = copyin(SCARG(uap, set), &nss, sizeof(nss)); 141b07ec3fcSad if (error) 1423c74cdf1Srmind return error; 143b07ec3fcSad } 144284c2b9aSad mutex_enter(p->p_lock); 145b07ec3fcSad error = sigprocmask1(l, SCARG(uap, how), 146b07ec3fcSad SCARG(uap, set) ? &nss : 0, SCARG(uap, oset) ? &oss : 0); 147284c2b9aSad mutex_exit(p->p_lock); 148b07ec3fcSad if (error) 1493c74cdf1Srmind return error; 150b07ec3fcSad if (SCARG(uap, oset)) { 151b07ec3fcSad error = copyout(&oss, SCARG(uap, oset), sizeof(oss)); 152b07ec3fcSad if (error) 1533c74cdf1Srmind return error; 154b07ec3fcSad } 1553c74cdf1Srmind return 0; 156b07ec3fcSad } 157b07ec3fcSad 158b07ec3fcSad int 1593c74cdf1Srmind sys___sigpending14(struct lwp *l, const struct sys___sigpending14_args *uap, 1603c74cdf1Srmind register_t *retval) 161b07ec3fcSad { 1627e2790cfSdsl /* { 163b07ec3fcSad syscallarg(sigset_t *) set; 1647e2790cfSdsl } */ 165b07ec3fcSad sigset_t ss; 166b07ec3fcSad 167b07ec3fcSad sigpending1(l, &ss); 1683c74cdf1Srmind return copyout(&ss, SCARG(uap, set), sizeof(ss)); 169b07ec3fcSad } 170b07ec3fcSad 171b07ec3fcSad /* 172b07ec3fcSad * Suspend process until signal, providing mask to be set in the meantime. 173b07ec3fcSad * Note nonstandard calling convention: libc stub passes mask, not pointer, 174b07ec3fcSad * to save a copyin. 175b07ec3fcSad */ 176b07ec3fcSad int 1773c74cdf1Srmind sys___sigsuspend14(struct lwp *l, const struct sys___sigsuspend14_args *uap, 1783c74cdf1Srmind register_t *retval) 179b07ec3fcSad { 1807e2790cfSdsl /* { 181b07ec3fcSad syscallarg(const sigset_t *) set; 1827e2790cfSdsl } */ 183b07ec3fcSad sigset_t ss; 184b07ec3fcSad int error; 185b07ec3fcSad 186b07ec3fcSad if (SCARG(uap, set)) { 187b07ec3fcSad error = copyin(SCARG(uap, set), &ss, sizeof(ss)); 188b07ec3fcSad if (error) 1893c74cdf1Srmind return error; 1903c74cdf1Srmind } 1913c74cdf1Srmind return sigsuspend1(l, SCARG(uap, set) ? &ss : 0); 192b07ec3fcSad } 193b07ec3fcSad 194b07ec3fcSad int 1953c74cdf1Srmind sys___sigaltstack14(struct lwp *l, const struct sys___sigaltstack14_args *uap, 1963c74cdf1Srmind register_t *retval) 197b07ec3fcSad { 1987e2790cfSdsl /* { 199b07ec3fcSad syscallarg(const struct sigaltstack *) nss; 200b07ec3fcSad syscallarg(struct sigaltstack *) oss; 2017e2790cfSdsl } */ 202b07ec3fcSad struct sigaltstack nss, oss; 203b07ec3fcSad int error; 204b07ec3fcSad 205b07ec3fcSad if (SCARG(uap, nss)) { 206b07ec3fcSad error = copyin(SCARG(uap, nss), &nss, sizeof(nss)); 207b07ec3fcSad if (error) 2083c74cdf1Srmind return error; 209b07ec3fcSad } 210b07ec3fcSad error = sigaltstack1(l, 211b07ec3fcSad SCARG(uap, nss) ? &nss : 0, SCARG(uap, oss) ? &oss : 0); 212b07ec3fcSad if (error) 2133c74cdf1Srmind return error; 214b07ec3fcSad if (SCARG(uap, oss)) { 215b07ec3fcSad error = copyout(&oss, SCARG(uap, oss), sizeof(oss)); 216b07ec3fcSad if (error) 2173c74cdf1Srmind return error; 218b07ec3fcSad } 2193c74cdf1Srmind return 0; 220b07ec3fcSad } 221b07ec3fcSad 2225f7e4ad4Smartin int 2233d70c4b4Schristos kill1(struct lwp *l, pid_t pid, ksiginfo_t *ksi, register_t *retval) 2243d70c4b4Schristos { 2253d70c4b4Schristos int error; 2263d70c4b4Schristos struct proc *p; 2273d70c4b4Schristos 2283d70c4b4Schristos if ((u_int)ksi->ksi_signo >= NSIG) 2293c74cdf1Srmind return EINVAL; 2303d70c4b4Schristos 231ccc5092eSmartin if (pid != l->l_proc->p_pid) { 2323d70c4b4Schristos if (ksi->ksi_pid != l->l_proc->p_pid) 2333d70c4b4Schristos return EPERM; 2343d70c4b4Schristos 2353d70c4b4Schristos if (ksi->ksi_uid != kauth_cred_geteuid(l->l_cred)) 2363d70c4b4Schristos return EPERM; 2373d70c4b4Schristos 2383d70c4b4Schristos switch (ksi->ksi_code) { 2393d70c4b4Schristos case SI_USER: 2403d70c4b4Schristos case SI_QUEUE: 2413d70c4b4Schristos break; 2423d70c4b4Schristos default: 2433d70c4b4Schristos return EPERM; 2443d70c4b4Schristos } 245ccc5092eSmartin } 2463d70c4b4Schristos 2473d70c4b4Schristos if (pid > 0) { 248b07ec3fcSad /* kill single process */ 2496d70f903Sad mutex_enter(proc_lock); 250c296146aSchristos p = proc_find_raw(pid); 251c296146aSchristos if (p == NULL || (p->p_stat != SACTIVE && p->p_stat != SSTOP)) { 2526d70f903Sad mutex_exit(proc_lock); 253c296146aSchristos /* IEEE Std 1003.1-2001: return success for zombies */ 254c296146aSchristos return p ? 0 : ESRCH; 2556d70f903Sad } 256284c2b9aSad mutex_enter(p->p_lock); 257b07ec3fcSad error = kauth_authorize_process(l->l_cred, 2583d70c4b4Schristos KAUTH_PROCESS_SIGNAL, p, KAUTH_ARG(ksi->ksi_signo), 259b07ec3fcSad NULL, NULL); 2603d70c4b4Schristos if (!error && ksi->ksi_signo) { 2613d70c4b4Schristos kpsignal2(p, ksi); 262b07ec3fcSad } 263284c2b9aSad mutex_exit(p->p_lock); 2646d70f903Sad mutex_exit(proc_lock); 2653c74cdf1Srmind return error; 266b07ec3fcSad } 2673d70c4b4Schristos 2683d70c4b4Schristos switch (pid) { 269b07ec3fcSad case -1: /* broadcast signal */ 2703d70c4b4Schristos return killpg1(l, ksi, 0, 1); 271b07ec3fcSad case 0: /* signal own process group */ 2723d70c4b4Schristos return killpg1(l, ksi, 0, 0); 273b07ec3fcSad default: /* negative explicit process group */ 2743d70c4b4Schristos return killpg1(l, ksi, -pid, 0); 275b07ec3fcSad } 276b07ec3fcSad /* NOTREACHED */ 277b07ec3fcSad } 278b07ec3fcSad 279b07ec3fcSad int 2803d70c4b4Schristos sys_sigqueueinfo(struct lwp *l, const struct sys_sigqueueinfo_args *uap, 2813d70c4b4Schristos register_t *retval) 2823d70c4b4Schristos { 2833d70c4b4Schristos /* { 2843d70c4b4Schristos syscallarg(pid_t int) pid; 2853d70c4b4Schristos syscallarg(const siginfo_t *) info; 2863d70c4b4Schristos } */ 2873d70c4b4Schristos ksiginfo_t ksi; 2883d70c4b4Schristos int error; 2893d70c4b4Schristos 2903d70c4b4Schristos KSI_INIT(&ksi); 2913d70c4b4Schristos 2923d70c4b4Schristos if ((error = copyin(&SCARG(uap, info)->_info, &ksi.ksi_info, 2933d70c4b4Schristos sizeof(ksi.ksi_info))) != 0) 2943d70c4b4Schristos return error; 2953d70c4b4Schristos 2963d70c4b4Schristos return kill1(l, SCARG(uap, pid), &ksi, retval); 2973d70c4b4Schristos } 2983d70c4b4Schristos 2993d70c4b4Schristos int 3003d70c4b4Schristos sys_kill(struct lwp *l, const struct sys_kill_args *uap, register_t *retval) 3013d70c4b4Schristos { 3023d70c4b4Schristos /* { 3033d70c4b4Schristos syscallarg(pid_t) pid; 3043d70c4b4Schristos syscallarg(int) signum; 3053d70c4b4Schristos } */ 3063d70c4b4Schristos ksiginfo_t ksi; 3073d70c4b4Schristos 3083d70c4b4Schristos KSI_INIT(&ksi); 3093d70c4b4Schristos 3103d70c4b4Schristos ksi.ksi_signo = SCARG(uap, signum); 3113d70c4b4Schristos ksi.ksi_code = SI_USER; 3123d70c4b4Schristos ksi.ksi_pid = l->l_proc->p_pid; 3133d70c4b4Schristos ksi.ksi_uid = kauth_cred_geteuid(l->l_cred); 3143d70c4b4Schristos 3153d70c4b4Schristos return kill1(l, SCARG(uap, pid), &ksi, retval); 3163d70c4b4Schristos } 3173d70c4b4Schristos 3183d70c4b4Schristos int 3193c74cdf1Srmind sys_getcontext(struct lwp *l, const struct sys_getcontext_args *uap, 3203c74cdf1Srmind register_t *retval) 321b07ec3fcSad { 3227e2790cfSdsl /* { 323b07ec3fcSad syscallarg(struct __ucontext *) ucp; 3247e2790cfSdsl } */ 325b07ec3fcSad struct proc *p = l->l_proc; 326b07ec3fcSad ucontext_t uc; 327b07ec3fcSad 32813011308Sjoerg memset(&uc, 0, sizeof(uc)); 32913011308Sjoerg 330284c2b9aSad mutex_enter(p->p_lock); 331b07ec3fcSad getucontext(l, &uc); 332284c2b9aSad mutex_exit(p->p_lock); 333b07ec3fcSad 3343c74cdf1Srmind return copyout(&uc, SCARG(uap, ucp), sizeof (*SCARG(uap, ucp))); 335b07ec3fcSad } 336b07ec3fcSad 337b07ec3fcSad int 3383c74cdf1Srmind sys_setcontext(struct lwp *l, const struct sys_setcontext_args *uap, 3393c74cdf1Srmind register_t *retval) 340b07ec3fcSad { 3417e2790cfSdsl /* { 342b07ec3fcSad syscallarg(const ucontext_t *) ucp; 3437e2790cfSdsl } */ 344b07ec3fcSad struct proc *p = l->l_proc; 345b07ec3fcSad ucontext_t uc; 346b07ec3fcSad int error; 347b07ec3fcSad 348b07ec3fcSad error = copyin(SCARG(uap, ucp), &uc, sizeof (uc)); 349b07ec3fcSad if (error) 3503c74cdf1Srmind return error; 3513c74cdf1Srmind if ((uc.uc_flags & _UC_CPU) == 0) 3523c74cdf1Srmind return EINVAL; 353284c2b9aSad mutex_enter(p->p_lock); 354b07ec3fcSad error = setucontext(l, &uc); 355284c2b9aSad mutex_exit(p->p_lock); 356b07ec3fcSad if (error) 3573c74cdf1Srmind return error; 358b07ec3fcSad 3593c74cdf1Srmind return EJUSTRETURN; 360b07ec3fcSad } 361b07ec3fcSad 362b07ec3fcSad /* 363b07ec3fcSad * sigtimedwait(2) system call, used also for implementation 364b07ec3fcSad * of sigwaitinfo() and sigwait(). 365b07ec3fcSad * 366b07ec3fcSad * This only handles single LWP in signal wait. libpthread provides 367f0a7346dSsnj * its own sigtimedwait() wrapper to DTRT WRT individual threads. 368b07ec3fcSad */ 369b07ec3fcSad int 370461a86f9Schristos sys_____sigtimedwait50(struct lwp *l, 371461a86f9Schristos const struct sys_____sigtimedwait50_args *uap, register_t *retval) 372b07ec3fcSad { 373b07ec3fcSad 374d8bca0f2Schristos return sigtimedwait1(l, uap, retval, copyin, copyout, copyin, copyout); 375b07ec3fcSad } 376b07ec3fcSad 377b07ec3fcSad int 378b07ec3fcSad sigaction1(struct lwp *l, int signum, const struct sigaction *nsa, 379b07ec3fcSad struct sigaction *osa, const void *tramp, int vers) 380b07ec3fcSad { 381b07ec3fcSad struct proc *p; 382b07ec3fcSad struct sigacts *ps; 383b07ec3fcSad sigset_t tset; 384b07ec3fcSad int prop, error; 385b07ec3fcSad ksiginfoq_t kq; 3869d09ecfaSad static bool v0v1valid; 387b07ec3fcSad 388b07ec3fcSad if (signum <= 0 || signum >= NSIG) 3893c74cdf1Srmind return EINVAL; 390b07ec3fcSad 391b07ec3fcSad p = l->l_proc; 392b07ec3fcSad error = 0; 393b07ec3fcSad ksiginfo_queue_init(&kq); 394b07ec3fcSad 395b07ec3fcSad /* 396b07ec3fcSad * Trampoline ABI version 0 is reserved for the legacy kernel 397b07ec3fcSad * provided on-stack trampoline. Conversely, if we are using a 398b07ec3fcSad * non-0 ABI version, we must have a trampoline. Only validate the 399b9e9a610Schristos * vers if a new sigaction was supplied and there was an actual 400b9e9a610Schristos * handler specified (not SIG_IGN or SIG_DFL), which don't require 401b9e9a610Schristos * a trampoline. Emulations use legacy kernel trampolines with 402b9e9a610Schristos * version 0, alternatively check for that too. 40392ce8c6aSad * 40492ce8c6aSad * If version < 2, we try to autoload the compat module. Note 40592ce8c6aSad * that we interlock with the unload check in compat_modcmd() 40623d5409eSpgoyette * using kernconfig_lock. If the autoload fails, we don't try it 40792ce8c6aSad * again for this process. 408b07ec3fcSad */ 409b9e9a610Schristos if (nsa != NULL && nsa->sa_handler != SIG_IGN 410b9e9a610Schristos && nsa->sa_handler != SIG_DFL) { 411131cc4dfSchristos if (__predict_false(vers < 2)) { 412131cc4dfSchristos if (p->p_flag & PK_32) 413131cc4dfSchristos v0v1valid = true; 414131cc4dfSchristos else if ((p->p_lflag & PL_SIGCOMPAT) == 0) { 41523d5409eSpgoyette kernconfig_lock(); 41692ce8c6aSad if (sendsig_sigcontext_vec == NULL) { 4179d09ecfaSad (void)module_autoload("compat", 4189d09ecfaSad MODULE_CLASS_ANY); 4199d09ecfaSad } 4209d09ecfaSad if (sendsig_sigcontext_vec != NULL) { 4219d09ecfaSad /* 4229d09ecfaSad * We need to remember if the 4239d09ecfaSad * sigcontext method may be useable, 4249d09ecfaSad * because libc may use it even 4259d09ecfaSad * if siginfo is available. 4269d09ecfaSad */ 4279d09ecfaSad v0v1valid = true; 42892ce8c6aSad } 42992ce8c6aSad mutex_enter(proc_lock); 4309d09ecfaSad /* 4319d09ecfaSad * Prevent unload of compat module while 4329d09ecfaSad * this process remains. 4339d09ecfaSad */ 43492ce8c6aSad p->p_lflag |= PL_SIGCOMPAT; 43592ce8c6aSad mutex_exit(proc_lock); 43623d5409eSpgoyette kernconfig_unlock(); 43792ce8c6aSad } 438131cc4dfSchristos } 43992ce8c6aSad 4409d09ecfaSad switch (vers) { 4419d09ecfaSad case 0: 4429d09ecfaSad /* sigcontext, kernel supplied trampoline. */ 4439d09ecfaSad if (tramp != NULL || !v0v1valid) { 44492ce8c6aSad return EINVAL; 44592ce8c6aSad } 4469d09ecfaSad break; 4479d09ecfaSad case 1: 4489d09ecfaSad /* sigcontext, user supplied trampoline. */ 4499d09ecfaSad if (tramp == NULL || !v0v1valid) { 45092ce8c6aSad return EINVAL; 451b07ec3fcSad } 4529d09ecfaSad break; 4539d09ecfaSad case 2: 4549d09ecfaSad case 3: 4559d09ecfaSad /* siginfo, user supplied trampoline. */ 4569d09ecfaSad if (tramp == NULL) { 4579d09ecfaSad return EINVAL; 4589d09ecfaSad } 4599d09ecfaSad break; 4609d09ecfaSad default: 4619d09ecfaSad return EINVAL; 4629d09ecfaSad } 4639d09ecfaSad } 464b07ec3fcSad 465284c2b9aSad mutex_enter(p->p_lock); 466b07ec3fcSad 467b07ec3fcSad ps = p->p_sigacts; 468b07ec3fcSad if (osa) 469b07ec3fcSad *osa = SIGACTION_PS(ps, signum); 470b07ec3fcSad if (!nsa) 471b07ec3fcSad goto out; 472b07ec3fcSad 473b07ec3fcSad prop = sigprop[signum]; 474b07ec3fcSad if ((nsa->sa_flags & ~SA_ALLBITS) || (prop & SA_CANTMASK)) { 475b07ec3fcSad error = EINVAL; 476b07ec3fcSad goto out; 477b07ec3fcSad } 478b07ec3fcSad 479b07ec3fcSad SIGACTION_PS(ps, signum) = *nsa; 480b07ec3fcSad ps->sa_sigdesc[signum].sd_tramp = tramp; 481b07ec3fcSad ps->sa_sigdesc[signum].sd_vers = vers; 482b07ec3fcSad sigminusset(&sigcantmask, &SIGACTION_PS(ps, signum).sa_mask); 483b07ec3fcSad 484b07ec3fcSad if ((prop & SA_NORESET) != 0) 485b07ec3fcSad SIGACTION_PS(ps, signum).sa_flags &= ~SA_RESETHAND; 486b07ec3fcSad 487b07ec3fcSad if (signum == SIGCHLD) { 488b07ec3fcSad if (nsa->sa_flags & SA_NOCLDSTOP) 489b07ec3fcSad p->p_sflag |= PS_NOCLDSTOP; 490b07ec3fcSad else 491b07ec3fcSad p->p_sflag &= ~PS_NOCLDSTOP; 492b07ec3fcSad if (nsa->sa_flags & SA_NOCLDWAIT) { 493b07ec3fcSad /* 494b07ec3fcSad * Paranoia: since SA_NOCLDWAIT is implemented by 495b07ec3fcSad * reparenting the dying child to PID 1 (and trust 496b07ec3fcSad * it to reap the zombie), PID 1 itself is forbidden 497b07ec3fcSad * to set SA_NOCLDWAIT. 498b07ec3fcSad */ 499b07ec3fcSad if (p->p_pid == 1) 500934634a1Spavel p->p_flag &= ~PK_NOCLDWAIT; 501b07ec3fcSad else 502934634a1Spavel p->p_flag |= PK_NOCLDWAIT; 503b07ec3fcSad } else 504934634a1Spavel p->p_flag &= ~PK_NOCLDWAIT; 505b07ec3fcSad 506b07ec3fcSad if (nsa->sa_handler == SIG_IGN) { 507b07ec3fcSad /* 508b07ec3fcSad * Paranoia: same as above. 509b07ec3fcSad */ 510b07ec3fcSad if (p->p_pid == 1) 511934634a1Spavel p->p_flag &= ~PK_CLDSIGIGN; 512b07ec3fcSad else 513934634a1Spavel p->p_flag |= PK_CLDSIGIGN; 514b07ec3fcSad } else 515934634a1Spavel p->p_flag &= ~PK_CLDSIGIGN; 516b07ec3fcSad } 517b07ec3fcSad 518b07ec3fcSad if ((nsa->sa_flags & SA_NODEFER) == 0) 519b07ec3fcSad sigaddset(&SIGACTION_PS(ps, signum).sa_mask, signum); 520b07ec3fcSad else 521b07ec3fcSad sigdelset(&SIGACTION_PS(ps, signum).sa_mask, signum); 522b07ec3fcSad 523b07ec3fcSad /* 524b07ec3fcSad * Set bit in p_sigctx.ps_sigignore for signals that are set to 525b07ec3fcSad * SIG_IGN, and for signals set to SIG_DFL where the default is to 526b07ec3fcSad * ignore. However, don't put SIGCONT in p_sigctx.ps_sigignore, as 527b07ec3fcSad * we have to restart the process. 528b07ec3fcSad */ 529b07ec3fcSad if (nsa->sa_handler == SIG_IGN || 530b07ec3fcSad (nsa->sa_handler == SIG_DFL && (prop & SA_IGNORE) != 0)) { 531b07ec3fcSad /* Never to be seen again. */ 532b07ec3fcSad sigemptyset(&tset); 533b07ec3fcSad sigaddset(&tset, signum); 534b07ec3fcSad sigclearall(p, &tset, &kq); 535b07ec3fcSad if (signum != SIGCONT) { 536b07ec3fcSad /* Easier in psignal */ 537b07ec3fcSad sigaddset(&p->p_sigctx.ps_sigignore, signum); 538b07ec3fcSad } 539b07ec3fcSad sigdelset(&p->p_sigctx.ps_sigcatch, signum); 540b07ec3fcSad } else { 541b07ec3fcSad sigdelset(&p->p_sigctx.ps_sigignore, signum); 542b07ec3fcSad if (nsa->sa_handler == SIG_DFL) 543b07ec3fcSad sigdelset(&p->p_sigctx.ps_sigcatch, signum); 544b07ec3fcSad else 545b07ec3fcSad sigaddset(&p->p_sigctx.ps_sigcatch, signum); 546b07ec3fcSad } 547b07ec3fcSad 548b07ec3fcSad /* 549b07ec3fcSad * Previously held signals may now have become visible. Ensure that 550b07ec3fcSad * we check for them before returning to userspace. 551b07ec3fcSad */ 552a76d1d29Sad if (sigispending(l, 0)) { 553b07ec3fcSad lwp_lock(l); 554934634a1Spavel l->l_flag |= LW_PENDSIG; 555b07ec3fcSad lwp_unlock(l); 556a76d1d29Sad } 557b07ec3fcSad out: 558284c2b9aSad mutex_exit(p->p_lock); 559b07ec3fcSad ksiginfo_queue_drain(&kq); 560b07ec3fcSad 5613c74cdf1Srmind return error; 562b07ec3fcSad } 563b07ec3fcSad 564b07ec3fcSad int 565b07ec3fcSad sigprocmask1(struct lwp *l, int how, const sigset_t *nss, sigset_t *oss) 566b07ec3fcSad { 567ad12c770Srmind sigset_t *mask = &l->l_sigmask; 568ad12c770Srmind bool more; 569b07ec3fcSad 570ad12c770Srmind KASSERT(mutex_owned(l->l_proc->p_lock)); 571b07ec3fcSad 572ad12c770Srmind if (oss) { 573fc7511b0Swrstuden *oss = *mask; 574ad12c770Srmind } 575ad12c770Srmind 576ad12c770Srmind if (nss == NULL) { 577ad12c770Srmind return 0; 578ad12c770Srmind } 579ad12c770Srmind 580b07ec3fcSad switch (how) { 581b07ec3fcSad case SIG_BLOCK: 582fc7511b0Swrstuden sigplusset(nss, mask); 583ad12c770Srmind more = false; 584b07ec3fcSad break; 585b07ec3fcSad case SIG_UNBLOCK: 586fc7511b0Swrstuden sigminusset(nss, mask); 587ad12c770Srmind more = true; 588b07ec3fcSad break; 589b07ec3fcSad case SIG_SETMASK: 590fc7511b0Swrstuden *mask = *nss; 591ad12c770Srmind more = true; 592b07ec3fcSad break; 593b07ec3fcSad default: 594ad12c770Srmind return EINVAL; 595b07ec3fcSad } 596fc7511b0Swrstuden sigminusset(&sigcantmask, mask); 597a76d1d29Sad if (more && sigispending(l, 0)) { 598b07ec3fcSad /* 599b07ec3fcSad * Check for pending signals on return to user. 600b07ec3fcSad */ 601b07ec3fcSad lwp_lock(l); 602934634a1Spavel l->l_flag |= LW_PENDSIG; 603b07ec3fcSad lwp_unlock(l); 604b07ec3fcSad } 6053c74cdf1Srmind return 0; 606b07ec3fcSad } 607b07ec3fcSad 608b07ec3fcSad void 609b07ec3fcSad sigpending1(struct lwp *l, sigset_t *ss) 610b07ec3fcSad { 611b07ec3fcSad struct proc *p = l->l_proc; 612b07ec3fcSad 613284c2b9aSad mutex_enter(p->p_lock); 614b07ec3fcSad *ss = l->l_sigpend.sp_set; 615b07ec3fcSad sigplusset(&p->p_sigpend.sp_set, ss); 616284c2b9aSad mutex_exit(p->p_lock); 617b07ec3fcSad } 618b07ec3fcSad 619e2543d03Schristos void 620e2543d03Schristos sigsuspendsetup(struct lwp *l, const sigset_t *ss) 621b07ec3fcSad { 6223c74cdf1Srmind struct proc *p = l->l_proc; 623b07ec3fcSad 624b07ec3fcSad /* 625e2543d03Schristos * When returning from sigsuspend/pselect/pollts, we want 626b07ec3fcSad * the old mask to be restored after the 627b07ec3fcSad * signal handler has finished. Thus, we 628b07ec3fcSad * save it here and mark the sigctx structure 629b07ec3fcSad * to indicate this. 630b07ec3fcSad */ 631284c2b9aSad mutex_enter(p->p_lock); 632b07ec3fcSad l->l_sigrestore = 1; 633b07ec3fcSad l->l_sigoldmask = l->l_sigmask; 634b07ec3fcSad l->l_sigmask = *ss; 635b07ec3fcSad sigminusset(&sigcantmask, &l->l_sigmask); 636b07ec3fcSad 637b07ec3fcSad /* Check for pending signals when sleeping. */ 638a76d1d29Sad if (sigispending(l, 0)) { 639b07ec3fcSad lwp_lock(l); 640934634a1Spavel l->l_flag |= LW_PENDSIG; 641b07ec3fcSad lwp_unlock(l); 642a76d1d29Sad } 643284c2b9aSad mutex_exit(p->p_lock); 644b07ec3fcSad } 645b07ec3fcSad 6460b60c7beSchristos void 6470b60c7beSchristos sigsuspendteardown(struct lwp *l) 6480b60c7beSchristos { 6490b60c7beSchristos struct proc *p = l->l_proc; 6500b60c7beSchristos 6510b60c7beSchristos mutex_enter(p->p_lock); 65241ceba00Schristos /* Check for pending signals when sleeping. */ 6530b60c7beSchristos if (l->l_sigrestore) { 65441ceba00Schristos if (sigispending(l, 0)) { 65541ceba00Schristos lwp_lock(l); 65641ceba00Schristos l->l_flag |= LW_PENDSIG; 65741ceba00Schristos lwp_unlock(l); 65841ceba00Schristos } else { 6590b60c7beSchristos l->l_sigrestore = 0; 6600b60c7beSchristos l->l_sigmask = l->l_sigoldmask; 6610b60c7beSchristos } 66241ceba00Schristos } 6630b60c7beSchristos mutex_exit(p->p_lock); 6640b60c7beSchristos } 6650b60c7beSchristos 666e2543d03Schristos int 667e2543d03Schristos sigsuspend1(struct lwp *l, const sigset_t *ss) 668e2543d03Schristos { 669e2543d03Schristos 670e2543d03Schristos if (ss) 671e2543d03Schristos sigsuspendsetup(l, ss); 672e2543d03Schristos 6734f3d5a9cSthorpej while (kpause("pause", true, 0, NULL) == 0) 674b07ec3fcSad ; 675b07ec3fcSad 676b07ec3fcSad /* always return EINTR rather than ERESTART... */ 6773c74cdf1Srmind return EINTR; 678b07ec3fcSad } 679b07ec3fcSad 680b07ec3fcSad int 681b07ec3fcSad sigaltstack1(struct lwp *l, const struct sigaltstack *nss, 682b07ec3fcSad struct sigaltstack *oss) 683b07ec3fcSad { 684b07ec3fcSad struct proc *p = l->l_proc; 685b07ec3fcSad int error = 0; 686b07ec3fcSad 687284c2b9aSad mutex_enter(p->p_lock); 688b07ec3fcSad 689b07ec3fcSad if (oss) 690b07ec3fcSad *oss = l->l_sigstk; 691b07ec3fcSad 692b07ec3fcSad if (nss) { 693b07ec3fcSad if (nss->ss_flags & ~SS_ALLBITS) 694b07ec3fcSad error = EINVAL; 695b07ec3fcSad else if (nss->ss_flags & SS_DISABLE) { 696b07ec3fcSad if (l->l_sigstk.ss_flags & SS_ONSTACK) 697b07ec3fcSad error = EINVAL; 698b07ec3fcSad } else if (nss->ss_size < MINSIGSTKSZ) 699b07ec3fcSad error = ENOMEM; 700b07ec3fcSad 701b07ec3fcSad if (!error) 702b07ec3fcSad l->l_sigstk = *nss; 703b07ec3fcSad } 704b07ec3fcSad 705284c2b9aSad mutex_exit(p->p_lock); 706b07ec3fcSad 7073c74cdf1Srmind return error; 708b07ec3fcSad } 709b07ec3fcSad 710b07ec3fcSad int 711654415b2Spooka sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap, 712d8bca0f2Schristos register_t *retval, copyin_t fetchss, copyout_t storeinf, copyin_t fetchts, 713d8bca0f2Schristos copyout_t storets) 714b07ec3fcSad { 7157e2790cfSdsl /* { 716b07ec3fcSad syscallarg(const sigset_t *) set; 717b07ec3fcSad syscallarg(siginfo_t *) info; 718b07ec3fcSad syscallarg(struct timespec *) timeout; 7197e2790cfSdsl } */ 720b07ec3fcSad struct proc *p = l->l_proc; 7213c74cdf1Srmind int error, signum, timo; 722b07ec3fcSad struct timespec ts, tsstart, tsnow; 723ebd0ab14Srmind ksiginfo_t ksi; 724b07ec3fcSad 725b07ec3fcSad /* 726b07ec3fcSad * Calculate timeout, if it was specified. 7277c5d63e1Sapb * 7287c5d63e1Sapb * NULL pointer means an infinite timeout. 7297c5d63e1Sapb * {.tv_sec = 0, .tv_nsec = 0} means do not block. 730b07ec3fcSad */ 731b07ec3fcSad if (SCARG(uap, timeout)) { 7323c74cdf1Srmind error = (*fetchts)(SCARG(uap, timeout), &ts, sizeof(ts)); 7336e1db6ceSchristos if (error) 7346e1db6ceSchristos return error; 735b07ec3fcSad 7366e1db6ceSchristos if ((error = itimespecfix(&ts)) != 0) 7376e1db6ceSchristos return error; 738b07ec3fcSad 7396e1db6ceSchristos timo = tstohz(&ts); 740f92c0e46Sapb if (timo == 0) { 741f92c0e46Sapb if (ts.tv_sec == 0 && ts.tv_nsec == 0) 742f92c0e46Sapb timo = -1; /* do not block */ 743f92c0e46Sapb else 744f92c0e46Sapb timo = 1; /* the shortest possible timeout */ 745f92c0e46Sapb } 746b07ec3fcSad 747b07ec3fcSad /* 748b07ec3fcSad * Remember current uptime, it would be used in 749b07ec3fcSad * ECANCELED/ERESTART case. 750b07ec3fcSad */ 751b07ec3fcSad getnanouptime(&tsstart); 7523c74cdf1Srmind } else { 7533c74cdf1Srmind memset(&tsstart, 0, sizeof(tsstart)); /* XXXgcc */ 754f92c0e46Sapb timo = 0; /* infinite timeout */ 755b07ec3fcSad } 756b07ec3fcSad 757d8bca0f2Schristos error = (*fetchss)(SCARG(uap, set), &l->l_sigwaitset, 758b07ec3fcSad sizeof(l->l_sigwaitset)); 7593c74cdf1Srmind if (error) 7603c74cdf1Srmind return error; 761b07ec3fcSad 762b07ec3fcSad /* 763b07ec3fcSad * Silently ignore SA_CANTMASK signals. psignal1() would ignore 764b07ec3fcSad * SA_CANTMASK signals in waitset, we do this only for the below 765b07ec3fcSad * siglist check. 766b07ec3fcSad */ 767b07ec3fcSad sigminusset(&sigcantmask, &l->l_sigwaitset); 768b07ec3fcSad 769284c2b9aSad mutex_enter(p->p_lock); 770b07ec3fcSad 7713c74cdf1Srmind /* Check for pending signals in the process, if no - then in LWP. */ 772ebd0ab14Srmind if ((signum = sigget(&p->p_sigpend, &ksi, 0, &l->l_sigwaitset)) == 0) 773ebd0ab14Srmind signum = sigget(&l->l_sigpend, &ksi, 0, &l->l_sigwaitset); 774b07ec3fcSad 775b07ec3fcSad if (signum != 0) { 7763c74cdf1Srmind /* If found a pending signal, just copy it out to the user. */ 777284c2b9aSad mutex_exit(p->p_lock); 778b07ec3fcSad goto out; 779b07ec3fcSad } 780b07ec3fcSad 781f92c0e46Sapb if (timo < 0) { 782f92c0e46Sapb /* If not allowed to block, return an error */ 783f92c0e46Sapb mutex_exit(p->p_lock); 784f92c0e46Sapb return EAGAIN; 785f92c0e46Sapb } 786f92c0e46Sapb 787b07ec3fcSad /* 7883c74cdf1Srmind * Set up the sigwait list and wait for signal to arrive. 7893c74cdf1Srmind * We can either be woken up or time out. 790b07ec3fcSad */ 791ebd0ab14Srmind l->l_sigwaited = &ksi; 792b07ec3fcSad LIST_INSERT_HEAD(&p->p_sigwaiters, l, l_sigwaiter); 793284c2b9aSad error = cv_timedwait_sig(&l->l_sigcv, p->p_lock, timo); 794b07ec3fcSad 795b07ec3fcSad /* 7963c74cdf1Srmind * Need to find out if we woke as a result of _lwp_wakeup() or a 797b07ec3fcSad * signal outside our wait set. 798b07ec3fcSad */ 799b07ec3fcSad if (l->l_sigwaited != NULL) { 800b07ec3fcSad if (error == EINTR) { 8013c74cdf1Srmind /* Wakeup via _lwp_wakeup(). */ 802b07ec3fcSad error = ECANCELED; 803b07ec3fcSad } else if (!error) { 8043c74cdf1Srmind /* Spurious wakeup - arrange for syscall restart. */ 805b07ec3fcSad error = ERESTART; 806b07ec3fcSad } 807b07ec3fcSad l->l_sigwaited = NULL; 808b07ec3fcSad LIST_REMOVE(l, l_sigwaiter); 809b07ec3fcSad } 810284c2b9aSad mutex_exit(p->p_lock); 811b07ec3fcSad 812b07ec3fcSad /* 813b07ec3fcSad * If the sleep was interrupted (either by signal or wakeup), update 814b07ec3fcSad * the timeout and copyout new value back. It would be used when 815b07ec3fcSad * the syscall would be restarted or called again. 816b07ec3fcSad */ 817b07ec3fcSad if (timo && (error == ERESTART || error == ECANCELED)) { 818b07ec3fcSad getnanouptime(&tsnow); 819b07ec3fcSad 8203c74cdf1Srmind /* Compute how much time has passed since start. */ 821b07ec3fcSad timespecsub(&tsnow, &tsstart, &tsnow); 8223c74cdf1Srmind 8233c74cdf1Srmind /* Substract passed time from timeout. */ 824b07ec3fcSad timespecsub(&ts, &tsnow, &ts); 825b07ec3fcSad 826b07ec3fcSad if (ts.tv_sec < 0) 827b07ec3fcSad error = EAGAIN; 828b07ec3fcSad else { 8293c74cdf1Srmind /* Copy updated timeout to userland. */ 8303c74cdf1Srmind error = (*storets)(&ts, SCARG(uap, timeout), 831b07ec3fcSad sizeof(ts)); 832b07ec3fcSad } 833b07ec3fcSad } 8343c74cdf1Srmind out: 835b07ec3fcSad /* 836b07ec3fcSad * If a signal from the wait set arrived, copy it to userland. 837b07ec3fcSad * Copy only the used part of siginfo, the padding part is 838b07ec3fcSad * left unchanged (userland is not supposed to touch it anyway). 839b07ec3fcSad */ 8408239dc73Sdrochner if (error == 0 && SCARG(uap, info)) { 8413c74cdf1Srmind error = (*storeinf)(&ksi.ksi_info, SCARG(uap, info), 842ebd0ab14Srmind sizeof(ksi.ksi_info)); 8433c74cdf1Srmind } 844*db70f181Schristos if (error == 0) { 8458239dc73Sdrochner *retval = ksi.ksi_info._signo; 846*db70f181Schristos SDT_PROBE(proc, kernel, , signal__clear, *retval, 847*db70f181Schristos &ksi, 0, 0, 0); 848*db70f181Schristos } 849b07ec3fcSad return error; 850b07ec3fcSad } 851