1 /* $NetBSD: signals.c,v 1.17 2020/05/23 23:42:44 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 2010, 2011 Antti Kantee. All Rights Reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __KERNEL_RCSID(0, "$NetBSD: signals.c,v 1.17 2020/05/23 23:42:44 ad Exp $"); 30 31 #include <sys/param.h> 32 #include <sys/atomic.h> 33 #include <sys/event.h> 34 #include <sys/proc.h> 35 #include <sys/signal.h> 36 37 #include <rump-sys/kern.h> 38 39 #include <rump/rump.h> 40 #include <rump/rumpuser.h> 41 42 const struct filterops sig_filtops = { 43 .f_attach = (void *)eopnotsupp, 44 }; 45 46 sigset_t sigcantmask; 47 48 static void 49 pgrp_apply(struct pgrp *pgrp, int signo, void (*apply)(struct proc *p, int)) 50 { 51 struct proc *p; 52 53 KASSERT(mutex_owned(&proc_lock)); 54 55 LIST_FOREACH(p, &pgrp->pg_members, p_pglist) { 56 mutex_enter(p->p_lock); 57 apply(p, signo); 58 mutex_exit(p->p_lock); 59 } 60 } 61 62 /* RUMP_SIGMODEL_PANIC */ 63 64 static void 65 rumpsig_panic(struct proc *p, int signo) 66 { 67 68 switch (signo) { 69 case SIGSYS: 70 case SIGPIPE: 71 break; 72 default: 73 panic("unhandled signal %d", signo); 74 } 75 } 76 77 /* RUMP_SIGMODEL_IGNORE */ 78 79 static void 80 rumpsig_ignore(struct proc *p, int signo) 81 { 82 83 return; 84 } 85 86 /* RUMP_SIGMODEL_RAISE */ 87 88 static void 89 rumpsig_raise(struct proc *p, int signo) 90 { 91 92 if (RUMP_LOCALPROC_P(p)) { 93 rumpuser_kill(p->p_pid, signo); 94 } else { 95 rump_sysproxy_raise(RUMP_SPVM2CTL(p->p_vmspace), signo); 96 } 97 } 98 99 static void 100 rumpsig_record(struct proc *p, int signo) 101 { 102 103 if (!sigismember(&p->p_sigctx.ps_sigignore, signo)) { 104 sigaddset(&p->p_sigpend.sp_set, signo); 105 } 106 } 107 108 typedef void (*rumpsig_fn)(struct proc *, int); 109 110 static rumpsig_fn rumpsig = rumpsig_raise; 111 112 /* 113 * Set signal delivery model. It would be nice if we could 114 * take a functional argument. But then we'd need some 115 * OS independent way to represent a signal number and also 116 * a method for easy processing (parsing is boring). 117 * 118 * Plus, upcalls from the rump kernel into process space except 119 * via rumpuser is a somewhat gray area now. 120 */ 121 void 122 rump_boot_setsigmodel(enum rump_sigmodel model) 123 { 124 125 switch (model) { 126 case RUMP_SIGMODEL_PANIC: 127 rumpsig = rumpsig_panic; 128 break; 129 case RUMP_SIGMODEL_IGNORE: 130 rumpsig = rumpsig_ignore; 131 break; 132 case RUMP_SIGMODEL_RAISE: 133 rumpsig = rumpsig_raise; 134 break; 135 case RUMP_SIGMODEL_RECORD: 136 rumpsig = rumpsig_record; 137 break; 138 139 /* for compat, though I doubt anyone is using it */ 140 case RUMP_SIGMODEL__HOST_NOTANYMORE: 141 rumpsig = rumpsig_raise; 142 break; 143 } 144 } 145 146 void 147 psignal(struct proc *p, int sig) 148 { 149 150 rumpsig(p, sig); 151 } 152 153 void 154 pgsignal(struct pgrp *pgrp, int sig, int checktty) 155 { 156 157 pgrp_apply(pgrp, sig, rumpsig); 158 } 159 160 void 161 kpsignal(struct proc *p, ksiginfo_t *ksi, void *data) 162 { 163 164 rumpsig(p, ksi->ksi_signo); 165 } 166 167 void 168 kpgsignal(struct pgrp *pgrp, ksiginfo_t *ksi, void *data, int checkctty) 169 { 170 171 pgrp_apply(pgrp, ksi->ksi_signo, rumpsig); 172 } 173 174 int 175 sigispending(struct lwp *l, int signo) 176 { 177 struct proc *p = l->l_proc; 178 sigset_t tset; 179 180 tset = p->p_sigpend.sp_set; 181 182 if (signo == 0) { 183 if (firstsig(&tset) != 0) 184 return EINTR; 185 } else if (sigismember(&tset, signo)) 186 return EINTR; 187 return 0; 188 } 189 190 void 191 sigpending1(struct lwp *l, sigset_t *ss) 192 { 193 struct proc *p = l->l_proc; 194 195 mutex_enter(p->p_lock); 196 *ss = l->l_proc->p_sigpend.sp_set; 197 mutex_exit(p->p_lock); 198 } 199 200 int 201 sigismasked(struct lwp *l, int sig) 202 { 203 204 return sigismember(&l->l_proc->p_sigctx.ps_sigignore, sig); 205 } 206 207 void 208 sigclear(sigpend_t *sp, const sigset_t *mask, ksiginfoq_t *kq) 209 { 210 211 if (mask == NULL) 212 sigemptyset(&sp->sp_set); 213 else 214 sigminusset(mask, &sp->sp_set); 215 } 216 217 void 218 sigclearall(struct proc *p, const sigset_t *mask, ksiginfoq_t *kq) 219 { 220 221 /* don't assert proc lock, hence callable from user context */ 222 sigclear(&p->p_sigpend, mask, kq); 223 } 224 225 void 226 ksiginfo_queue_drain0(ksiginfoq_t *kq) 227 { 228 229 if (!(TAILQ_EMPTY(kq))) 230 panic("how did that get there?"); 231 } 232 233 int 234 sigprocmask1(struct lwp *l, int how, const sigset_t *nss, sigset_t *oss) 235 { 236 sigset_t *mask = &l->l_proc->p_sigctx.ps_sigignore; 237 238 KASSERT(mutex_owned(l->l_proc->p_lock)); 239 240 if (oss) 241 *oss = *mask; 242 243 if (nss) { 244 switch (how) { 245 case SIG_BLOCK: 246 sigplusset(nss, mask); 247 break; 248 case SIG_UNBLOCK: 249 sigminusset(nss, mask); 250 break; 251 case SIG_SETMASK: 252 *mask = *nss; 253 break; 254 default: 255 return EINVAL; 256 } 257 } 258 259 return 0; 260 } 261 262 void 263 siginit(struct proc *p) 264 { 265 266 sigemptyset(&p->p_sigctx.ps_sigignore); 267 sigemptyset(&p->p_sigpend.sp_set); 268 } 269 270 void 271 sigsuspendsetup(struct lwp *l, const sigset_t *ss) 272 { 273 /* XXX: Partial copy of kernel code, remove and use the kernel code. */ 274 struct proc *p = l->l_proc; 275 276 mutex_enter(p->p_lock); 277 l->l_sigrestore = 1; 278 l->l_sigoldmask = l->l_sigmask; 279 l->l_sigmask = *ss; 280 sigminusset(&sigcantmask, &l->l_sigmask); 281 mutex_exit(p->p_lock); 282 } 283 284 void 285 sigsuspendteardown(struct lwp *l) 286 { 287 /* XXX: Copy of kernel code, remove and use the kernel code. */ 288 struct proc *p = l->l_proc; 289 290 mutex_enter(p->p_lock); 291 if (l->l_sigrestore) { 292 l->l_sigrestore = 0; 293 l->l_sigmask = l->l_sigoldmask; 294 } 295 mutex_exit(p->p_lock); 296 } 297