1 /* $NetBSD: netbsd32_signal.c,v 1.39 2015/06/20 19:58:40 martin Exp $ */ 2 3 /* 4 * Copyright (c) 1998, 2001 Matthew R. Green 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: netbsd32_signal.c,v 1.39 2015/06/20 19:58:40 martin Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/mount.h> 35 #include <sys/stat.h> 36 #include <sys/time.h> 37 #include <sys/signalvar.h> 38 #include <sys/proc.h> 39 #include <sys/wait.h> 40 #include <sys/dirent.h> 41 42 #include <uvm/uvm_extern.h> 43 44 #include <compat/netbsd32/netbsd32.h> 45 #include <compat/netbsd32/netbsd32_conv.h> 46 #include <compat/netbsd32/netbsd32_syscallargs.h> 47 48 #include <compat/sys/signal.h> 49 #include <compat/sys/signalvar.h> 50 #include <compat/sys/siginfo.h> 51 #include <compat/sys/ucontext.h> 52 #include <compat/common/compat_sigaltstack.h> 53 54 55 int 56 netbsd32_sigaction(struct lwp *l, const struct netbsd32_sigaction_args *uap, register_t *retval) 57 { 58 /* { 59 syscallarg(int) signum; 60 syscallarg(const netbsd32_sigactionp_t) nsa; 61 syscallarg(netbsd32_sigactionp_t) osa; 62 } */ 63 struct sigaction nsa, osa; 64 struct netbsd32_sigaction13 *sa32p, sa32; 65 int error; 66 67 if (SCARG_P32(uap, nsa)) { 68 sa32p = SCARG_P32(uap, nsa); 69 if (copyin(sa32p, &sa32, sizeof(sa32))) 70 return EFAULT; 71 nsa.sa_handler = (void *)NETBSD32PTR64(sa32.netbsd32_sa_handler); 72 memset(&nsa.sa_mask, 0, sizeof(nsa.sa_mask)); 73 nsa.sa_mask.__bits[0] = sa32.netbsd32_sa_mask; 74 nsa.sa_flags = sa32.netbsd32_sa_flags; 75 } 76 error = sigaction1(l, SCARG(uap, signum), 77 SCARG_P32(uap, nsa) ? &nsa : 0, 78 SCARG_P32(uap, osa) ? &osa : 0, 79 NULL, 0); 80 81 if (error) 82 return (error); 83 84 if (SCARG_P32(uap, osa)) { 85 NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler); 86 sa32.netbsd32_sa_mask = osa.sa_mask.__bits[0]; 87 sa32.netbsd32_sa_flags = osa.sa_flags; 88 sa32p = SCARG_P32(uap, osa); 89 if (copyout(&sa32, sa32p, sizeof(sa32))) 90 return EFAULT; 91 } 92 93 return (0); 94 } 95 96 int 97 netbsd32___sigaltstack14(struct lwp *l, const struct netbsd32___sigaltstack14_args *uap, register_t *retval) 98 { 99 /* { 100 syscallarg(const netbsd32_sigaltstackp_t) nss; 101 syscallarg(netbsd32_sigaltstackp_t) oss; 102 } */ 103 compat_sigaltstack(uap, netbsd32_sigaltstack, SS_ONSTACK, SS_DISABLE); 104 } 105 106 /* ARGSUSED */ 107 int 108 netbsd32___sigaction14(struct lwp *l, const struct netbsd32___sigaction14_args *uap, register_t *retval) 109 { 110 /* { 111 syscallarg(int) signum; 112 syscallarg(const struct sigaction *) nsa; 113 syscallarg(struct sigaction *) osa; 114 } */ 115 struct netbsd32_sigaction sa32; 116 struct sigaction nsa, osa; 117 int error; 118 119 if (SCARG_P32(uap, nsa)) { 120 error = copyin(SCARG_P32(uap, nsa), &sa32, sizeof(sa32)); 121 if (error) 122 return (error); 123 nsa.sa_handler = NETBSD32PTR64(sa32.netbsd32_sa_handler); 124 nsa.sa_mask = sa32.netbsd32_sa_mask; 125 nsa.sa_flags = sa32.netbsd32_sa_flags; 126 } 127 error = sigaction1(l, SCARG(uap, signum), 128 SCARG_P32(uap, nsa) ? &nsa : 0, 129 SCARG_P32(uap, osa) ? &osa : 0, 130 NULL, 0); 131 if (error) 132 return (error); 133 if (SCARG_P32(uap, osa)) { 134 NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler); 135 sa32.netbsd32_sa_mask = osa.sa_mask; 136 sa32.netbsd32_sa_flags = osa.sa_flags; 137 error = copyout(&sa32, SCARG_P32(uap, osa), sizeof(sa32)); 138 if (error) 139 return (error); 140 } 141 return (0); 142 } 143 144 /* ARGSUSED */ 145 int 146 netbsd32___sigaction_sigtramp(struct lwp *l, const struct netbsd32___sigaction_sigtramp_args *uap, register_t *retval) 147 { 148 /* { 149 syscallarg(int) signum; 150 syscallarg(const netbsd32_sigactionp_t) nsa; 151 syscallarg(netbsd32_sigactionp_t) osa; 152 syscallarg(netbsd32_voidp) tramp; 153 syscallarg(int) vers; 154 } */ 155 struct netbsd32_sigaction sa32; 156 struct sigaction nsa, osa; 157 int error; 158 159 if (SCARG_P32(uap, nsa)) { 160 error = copyin(SCARG_P32(uap, nsa), &sa32, sizeof(sa32)); 161 if (error) 162 return (error); 163 nsa.sa_handler = NETBSD32PTR64(sa32.netbsd32_sa_handler); 164 nsa.sa_mask = sa32.netbsd32_sa_mask; 165 nsa.sa_flags = sa32.netbsd32_sa_flags; 166 } 167 error = sigaction1(l, SCARG(uap, signum), 168 SCARG_P32(uap, nsa) ? &nsa : 0, 169 SCARG_P32(uap, osa) ? &osa : 0, 170 SCARG_P32(uap, tramp), SCARG(uap, vers)); 171 if (error) 172 return (error); 173 if (SCARG_P32(uap, osa)) { 174 NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler); 175 sa32.netbsd32_sa_mask = osa.sa_mask; 176 sa32.netbsd32_sa_flags = osa.sa_flags; 177 error = copyout(&sa32, SCARG_P32(uap, osa), sizeof(sa32)); 178 if (error) 179 return (error); 180 } 181 return (0); 182 } 183 184 void 185 netbsd32_ksi32_to_ksi(struct _ksiginfo *si, const struct __ksiginfo32 *si32) 186 { 187 memset(si, 0, sizeof (*si)); 188 si->_signo = si32->_signo; 189 si->_code = si32->_code; 190 si->_errno = si32->_errno; 191 192 switch (si32->_signo) { 193 case SIGILL: 194 case SIGBUS: 195 case SIGSEGV: 196 case SIGFPE: 197 case SIGTRAP: 198 si->_reason._fault._addr = NETBSD32IPTR64(si32->_reason._fault._addr); 199 si->_reason._fault._trap = si32->_reason._fault._trap; 200 break; 201 case SIGALRM: 202 case SIGVTALRM: 203 case SIGPROF: 204 default: /* see sigqueue() and kill1() */ 205 si->_reason._rt._pid = si32->_reason._rt._pid; 206 si->_reason._rt._uid = si32->_reason._rt._uid; 207 si->_reason._rt._value.sival_int = si32->_reason._rt._value.sival_int; 208 break; 209 case SIGCHLD: 210 si->_reason._child._pid = si32->_reason._child._pid; 211 si->_reason._child._uid = si32->_reason._child._uid; 212 si->_reason._child._utime = si32->_reason._child._utime; 213 si->_reason._child._stime = si32->_reason._child._stime; 214 break; 215 case SIGURG: 216 case SIGIO: 217 si->_reason._poll._band = si32->_reason._poll._band; 218 si->_reason._poll._fd = si32->_reason._poll._fd; 219 break; 220 } 221 } 222 223 void 224 netbsd32_si_to_si32(siginfo32_t *si32, const siginfo_t *si) 225 { 226 memset(si32, 0, sizeof (*si32)); 227 si32->si_signo = si->si_signo; 228 si32->si_code = si->si_code; 229 si32->si_errno = si->si_errno; 230 231 switch (si32->si_signo) { 232 case 0: /* SA */ 233 si32->si_value.sival_int = si->si_value.sival_int; 234 break; 235 case SIGILL: 236 case SIGBUS: 237 case SIGSEGV: 238 case SIGFPE: 239 case SIGTRAP: 240 si32->si_addr = (uint32_t)(uintptr_t)si->si_addr; 241 si32->si_trap = si->si_trap; 242 break; 243 case SIGALRM: 244 case SIGVTALRM: 245 case SIGPROF: 246 default: 247 si32->si_pid = si->si_pid; 248 si32->si_uid = si->si_uid; 249 si32->si_value.sival_int = si->si_value.sival_int; 250 break; 251 case SIGCHLD: 252 si32->si_pid = si->si_pid; 253 si32->si_uid = si->si_uid; 254 si32->si_status = si->si_status; 255 si32->si_utime = si->si_utime; 256 si32->si_stime = si->si_stime; 257 break; 258 case SIGURG: 259 case SIGIO: 260 si32->si_band = si->si_band; 261 si32->si_fd = si->si_fd; 262 break; 263 } 264 } 265 266 void 267 getucontext32(struct lwp *l, ucontext32_t *ucp) 268 { 269 struct proc *p = l->l_proc; 270 271 KASSERT(mutex_owned(p->p_lock)); 272 273 ucp->uc_flags = 0; 274 ucp->uc_link = (uint32_t)(intptr_t)l->l_ctxlink; 275 ucp->uc_sigmask = l->l_sigmask; 276 ucp->uc_flags |= _UC_SIGMASK; 277 278 /* 279 * The (unsupplied) definition of the `current execution stack' 280 * in the System V Interface Definition appears to allow returning 281 * the main context stack. 282 */ 283 if ((l->l_sigstk.ss_flags & SS_ONSTACK) == 0) { 284 ucp->uc_stack.ss_sp = USRSTACK32; 285 ucp->uc_stack.ss_size = ctob(p->p_vmspace->vm_ssize); 286 ucp->uc_stack.ss_flags = 0; /* XXX, def. is Very Fishy */ 287 } else { 288 /* Simply copy alternate signal execution stack. */ 289 ucp->uc_stack.ss_sp = 290 (uint32_t)(intptr_t)l->l_sigstk.ss_sp; 291 ucp->uc_stack.ss_size = l->l_sigstk.ss_size; 292 ucp->uc_stack.ss_flags = l->l_sigstk.ss_flags; 293 } 294 ucp->uc_flags |= _UC_STACK; 295 mutex_exit(p->p_lock); 296 cpu_getmcontext32(l, &ucp->uc_mcontext, &ucp->uc_flags); 297 mutex_enter(p->p_lock); 298 } 299 300 int 301 netbsd32_getcontext(struct lwp *l, const struct netbsd32_getcontext_args *uap, register_t *retval) 302 { 303 /* { 304 syscallarg(netbsd32_ucontextp) ucp; 305 } */ 306 struct proc *p = l->l_proc; 307 ucontext32_t uc; 308 309 memset(&uc, 0, sizeof(uc)); 310 311 mutex_enter(p->p_lock); 312 getucontext32(l, &uc); 313 mutex_exit(p->p_lock); 314 315 return copyout(&uc, SCARG_P32(uap, ucp), sizeof (ucontext32_t)); 316 } 317 318 int 319 setucontext32(struct lwp *l, const ucontext32_t *ucp) 320 { 321 struct proc *p = l->l_proc; 322 int error; 323 324 KASSERT(mutex_owned(p->p_lock)); 325 326 if ((ucp->uc_flags & _UC_SIGMASK) != 0) { 327 error = sigprocmask1(l, SIG_SETMASK, &ucp->uc_sigmask, NULL); 328 if (error != 0) 329 return error; 330 } 331 332 mutex_exit(p->p_lock); 333 error = cpu_setmcontext32(l, &ucp->uc_mcontext, ucp->uc_flags); 334 mutex_enter(p->p_lock); 335 if (error != 0) 336 return (error); 337 338 l->l_ctxlink = (void *)(intptr_t)ucp->uc_link; 339 340 /* 341 * If there was stack information, update whether or not we are 342 * still running on an alternate signal stack. 343 */ 344 if ((ucp->uc_flags & _UC_STACK) != 0) { 345 if (ucp->uc_stack.ss_flags & SS_ONSTACK) 346 l->l_sigstk.ss_flags |= SS_ONSTACK; 347 else 348 l->l_sigstk.ss_flags &= ~SS_ONSTACK; 349 } 350 351 return 0; 352 } 353 354 /* ARGSUSED */ 355 int 356 netbsd32_setcontext(struct lwp *l, const struct netbsd32_setcontext_args *uap, register_t *retval) 357 { 358 /* { 359 syscallarg(netbsd32_ucontextp) ucp; 360 } */ 361 ucontext32_t uc; 362 int error; 363 struct proc *p = l->l_proc; 364 365 error = copyin(SCARG_P32(uap, ucp), &uc, sizeof (uc)); 366 if (error) 367 return (error); 368 if (!(uc.uc_flags & _UC_CPU)) 369 return (EINVAL); 370 mutex_enter(p->p_lock); 371 error = setucontext32(l, &uc); 372 mutex_exit(p->p_lock); 373 if (error) 374 return (error); 375 376 return (EJUSTRETURN); 377 } 378 379 static int 380 netbsd32_sigtimedwait_put_info(const void *src, void *dst, size_t size) 381 { 382 const siginfo_t *info = src; 383 siginfo32_t info32; 384 385 netbsd32_si_to_si32(&info32, info); 386 387 return copyout(&info32, dst, sizeof(info32)); 388 } 389 390 static int 391 netbsd32_sigtimedwait_fetch_timeout(const void *src, void *dst, size_t size) 392 { 393 struct timespec *ts = dst; 394 struct netbsd32_timespec ts32; 395 int error; 396 397 error = copyin(src, &ts32, sizeof(ts32)); 398 if (error) 399 return error; 400 401 netbsd32_to_timespec(&ts32, ts); 402 return 0; 403 } 404 405 static int 406 netbsd32_sigtimedwait_put_timeout(const void *src, void *dst, size_t size) 407 { 408 const struct timespec *ts = src; 409 struct netbsd32_timespec ts32; 410 411 netbsd32_from_timespec(ts, &ts32); 412 413 return copyout(&ts32, dst, sizeof(ts32)); 414 } 415 416 int 417 netbsd32_____sigtimedwait50(struct lwp *l, const struct netbsd32_____sigtimedwait50_args *uap, register_t *retval) 418 { 419 /* { 420 syscallarg(netbsd32_sigsetp_t) set; 421 syscallarg(netbsd32_siginfop_t) info; 422 syscallarg(netbsd32_timespec50p_t) timeout; 423 } */ 424 struct sys_____sigtimedwait50_args ua; 425 426 NETBSD32TOP_UAP(set, const sigset_t); 427 NETBSD32TOP_UAP(info, siginfo_t); 428 NETBSD32TOP_UAP(timeout, struct timespec); 429 430 return sigtimedwait1(l, &ua, retval, 431 copyin, 432 netbsd32_sigtimedwait_put_info, 433 netbsd32_sigtimedwait_fetch_timeout, 434 netbsd32_sigtimedwait_put_timeout); 435 } 436 437 int 438 netbsd32_sigqueueinfo(struct lwp *l, 439 const struct netbsd32_sigqueueinfo_args *uap, register_t *retval) 440 { 441 /* { 442 syscallarg(pid_t) pid; 443 syscallarg(const netbsd32_siginfop_t) info; 444 } */ 445 struct __ksiginfo32 ksi32; 446 ksiginfo_t ksi; 447 int error; 448 449 if ((error = copyin(SCARG_P32(uap, info), &ksi32, 450 sizeof(ksi32))) != 0) 451 return error; 452 453 KSI_INIT(&ksi); 454 netbsd32_ksi32_to_ksi(&ksi.ksi_info, &ksi32); 455 456 return kill1(l, SCARG(uap, pid), &ksi, retval); 457 } 458