1 /* $NetBSD: netbsd32_signal.c,v 1.52 2021/09/07 11:43:05 riastradh 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.52 2021/09/07 11:43:05 riastradh Exp $"); 31 32 #if defined(_KERNEL_OPT) 33 #include "opt_ktrace.h" 34 #endif 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/mount.h> 39 #include <sys/stat.h> 40 #include <sys/time.h> 41 #include <sys/signalvar.h> 42 #include <sys/ktrace.h> 43 #include <sys/proc.h> 44 #include <sys/wait.h> 45 #include <sys/dirent.h> 46 47 #include <uvm/uvm_extern.h> 48 49 #include <compat/netbsd32/netbsd32.h> 50 #include <compat/netbsd32/netbsd32_conv.h> 51 #include <compat/netbsd32/netbsd32_syscallargs.h> 52 53 #include <compat/sys/signal.h> 54 #include <compat/sys/signalvar.h> 55 #include <compat/sys/siginfo.h> 56 #include <compat/sys/ucontext.h> 57 #include <compat/common/compat_sigaltstack.h> 58 59 int 60 netbsd32_sigaction(struct lwp *l, const struct netbsd32_sigaction_args *uap, register_t *retval) 61 { 62 /* { 63 syscallarg(int) signum; 64 syscallarg(const netbsd32_sigactionp_t) nsa; 65 syscallarg(netbsd32_sigactionp_t) osa; 66 } */ 67 struct sigaction nsa, osa; 68 struct netbsd32_sigaction13 *sa32p, sa32; 69 int error; 70 71 if (SCARG_P32(uap, nsa)) { 72 sa32p = SCARG_P32(uap, nsa); 73 if (copyin(sa32p, &sa32, sizeof(sa32))) 74 return EFAULT; 75 nsa.sa_handler = (void *)NETBSD32PTR64(sa32.netbsd32_sa_handler); 76 memset(&nsa.sa_mask, 0, sizeof(nsa.sa_mask)); 77 nsa.sa_mask.__bits[0] = sa32.netbsd32_sa_mask; 78 nsa.sa_flags = sa32.netbsd32_sa_flags; 79 } 80 error = sigaction1(l, SCARG(uap, signum), 81 SCARG_P32(uap, nsa) ? &nsa : 0, 82 SCARG_P32(uap, osa) ? &osa : 0, 83 NULL, 0); 84 85 if (error) 86 return error; 87 88 if (SCARG_P32(uap, osa)) { 89 memset(&sa32, 0, sizeof(sa32)); 90 NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler); 91 sa32.netbsd32_sa_mask = osa.sa_mask.__bits[0]; 92 sa32.netbsd32_sa_flags = osa.sa_flags; 93 sa32p = SCARG_P32(uap, osa); 94 if (copyout(&sa32, sa32p, sizeof(sa32))) 95 return EFAULT; 96 } 97 98 return 0; 99 } 100 101 int 102 netbsd32___sigaltstack14(struct lwp *l, const struct netbsd32___sigaltstack14_args *uap, register_t *retval) 103 { 104 /* { 105 syscallarg(const netbsd32_sigaltstackp_t) nss; 106 syscallarg(netbsd32_sigaltstackp_t) oss; 107 } */ 108 compat_sigaltstack(uap, netbsd32_sigaltstack, SS_ONSTACK, SS_DISABLE); 109 } 110 111 /* ARGSUSED */ 112 int 113 netbsd32___sigaction14(struct lwp *l, const struct netbsd32___sigaction14_args *uap, register_t *retval) 114 { 115 /* { 116 syscallarg(int) signum; 117 syscallarg(const struct sigaction *) nsa; 118 syscallarg(struct sigaction *) osa; 119 } */ 120 struct netbsd32_sigaction sa32; 121 struct sigaction nsa, osa; 122 int error; 123 124 if (SCARG_P32(uap, nsa)) { 125 error = copyin(SCARG_P32(uap, nsa), &sa32, sizeof(sa32)); 126 if (error) 127 return error; 128 nsa.sa_handler = NETBSD32PTR64(sa32.netbsd32_sa_handler); 129 nsa.sa_mask = sa32.netbsd32_sa_mask; 130 nsa.sa_flags = sa32.netbsd32_sa_flags; 131 } 132 error = sigaction1(l, SCARG(uap, signum), 133 SCARG_P32(uap, nsa) ? &nsa : 0, 134 SCARG_P32(uap, osa) ? &osa : 0, 135 NULL, 0); 136 if (error) 137 return error; 138 if (SCARG_P32(uap, osa)) { 139 memset(&sa32, 0, sizeof(sa32)); 140 NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler); 141 sa32.netbsd32_sa_mask = osa.sa_mask; 142 sa32.netbsd32_sa_flags = osa.sa_flags; 143 error = copyout(&sa32, SCARG_P32(uap, osa), sizeof(sa32)); 144 if (error) 145 return error; 146 } 147 return 0; 148 } 149 150 /* ARGSUSED */ 151 int 152 netbsd32___sigaction_sigtramp(struct lwp *l, const struct netbsd32___sigaction_sigtramp_args *uap, register_t *retval) 153 { 154 /* { 155 syscallarg(int) signum; 156 syscallarg(const netbsd32_sigactionp_t) nsa; 157 syscallarg(netbsd32_sigactionp_t) osa; 158 syscallarg(netbsd32_voidp) tramp; 159 syscallarg(int) vers; 160 } */ 161 struct netbsd32_sigaction sa32; 162 struct sigaction nsa, osa; 163 int error; 164 165 if (SCARG_P32(uap, nsa)) { 166 error = copyin(SCARG_P32(uap, nsa), &sa32, sizeof(sa32)); 167 if (error) 168 return error; 169 nsa.sa_handler = NETBSD32PTR64(sa32.netbsd32_sa_handler); 170 nsa.sa_mask = sa32.netbsd32_sa_mask; 171 nsa.sa_flags = sa32.netbsd32_sa_flags; 172 } 173 error = sigaction1(l, SCARG(uap, signum), 174 SCARG_P32(uap, nsa) ? &nsa : 0, 175 SCARG_P32(uap, osa) ? &osa : 0, 176 SCARG_P32(uap, tramp), SCARG(uap, vers)); 177 if (error) 178 return error; 179 if (SCARG_P32(uap, osa)) { 180 memset(&sa32, 0, sizeof(sa32)); 181 NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler); 182 sa32.netbsd32_sa_mask = osa.sa_mask; 183 sa32.netbsd32_sa_flags = osa.sa_flags; 184 error = copyout(&sa32, SCARG_P32(uap, osa), sizeof(sa32)); 185 if (error) 186 return error; 187 } 188 return 0; 189 } 190 191 void 192 netbsd32_ksi32_to_ksi(struct _ksiginfo *si, const struct __ksiginfo32 *si32) 193 { 194 size_t i; 195 196 memset(si, 0, sizeof (*si)); 197 si->_signo = si32->_signo; 198 si->_code = si32->_code; 199 si->_errno = si32->_errno; 200 201 if (si32->_code == SI_NOINFO) 202 return; 203 else if (si32->_code <= 0) /* codes described in siginfo(2) */ 204 goto fill_rt; 205 206 switch (si32->_signo) { 207 case SIGILL: 208 case SIGFPE: 209 case SIGBUS: 210 case SIGSEGV: 211 fill_fault: 212 si->_reason._fault._addr = 213 NETBSD32IPTR64(si32->_reason._fault._addr); 214 si->_reason._fault._trap = si32->_reason._fault._trap; 215 break; 216 case SIGTRAP: 217 switch (si32->_code) { 218 case TRAP_EXEC: 219 break; 220 case TRAP_CHLD: 221 case TRAP_LWP: 222 si->_reason._ptrace_state._pe_report_event = 223 si32->_reason._ptrace_state._pe_report_event; 224 CTASSERT(sizeof(si->_reason._ptrace_state._option._pe_other_pid) == 225 sizeof(si->_reason._ptrace_state._option._pe_lwp)); 226 si->_reason._ptrace_state._option._pe_other_pid = 227 si32->_reason._ptrace_state._option._pe_other_pid; 228 break; 229 case TRAP_SCE: 230 case TRAP_SCX: 231 si->_reason._syscall._sysnum = 232 si32->_reason._syscall._sysnum; 233 si->_reason._syscall._retval[0] = 234 si32->_reason._syscall._retval[0]; 235 si->_reason._syscall._retval[1] = 236 si32->_reason._syscall._retval[1]; 237 si->_reason._syscall._error = 238 si32->_reason._syscall._error; 239 for (i = 0; 240 i < __arraycount(si->_reason._syscall._args); i++) 241 si->_reason._syscall._args[i] = 242 si32->_reason._syscall._args[i]; 243 break; 244 default: 245 goto fill_fault; 246 } 247 break; 248 case SIGALRM: 249 case SIGVTALRM: 250 case SIGPROF: 251 default: /* see sigqueue() and kill1() */ 252 fill_rt: 253 si->_reason._rt._pid = si32->_reason._rt._pid; 254 si->_reason._rt._uid = si32->_reason._rt._uid; 255 si->_reason._rt._value.sival_int = 256 si32->_reason._rt._value.sival_int; 257 break; 258 case SIGURG: 259 case SIGIO: 260 si->_reason._poll._band = si32->_reason._poll._band; 261 si->_reason._poll._fd = si32->_reason._poll._fd; 262 break; 263 case SIGCHLD: 264 si->_reason._child._pid = si32->_reason._child._pid; 265 si->_reason._child._uid = si32->_reason._child._uid; 266 si->_reason._child._status = si32->_reason._child._status; 267 si->_reason._child._utime = si32->_reason._child._utime; 268 si->_reason._child._stime = si32->_reason._child._stime; 269 break; 270 } 271 } 272 273 void 274 netbsd32_si32_to_si(siginfo_t *si, const siginfo32_t *si32) 275 { 276 277 memset(si, 0, sizeof (*si)); 278 netbsd32_ksi32_to_ksi(&si->_info, &si32->_info); 279 } 280 281 static void 282 netbsd32_ksi_to_ksi32(struct __ksiginfo32 *si32, const struct _ksiginfo *si) 283 { 284 size_t i; 285 286 memset(si32, 0, sizeof (*si32)); 287 si32->_signo = si->_signo; 288 si32->_code = si->_code; 289 si32->_errno = si->_errno; 290 291 if (si->_code == SI_NOINFO) 292 return; 293 else if (si->_code <= 0) /* codes described in siginfo(2) */ 294 goto fill_rt; 295 296 switch (si->_signo) { 297 case SIGILL: 298 case SIGFPE: 299 case SIGBUS: 300 case SIGSEGV: 301 fill_fault: 302 si32->_reason._fault._addr = 303 NETBSD32PTR32I(si->_reason._fault._addr); 304 si32->_reason._fault._trap = si->_reason._fault._trap; 305 break; 306 case SIGTRAP: 307 switch (si->_code) { 308 case TRAP_EXEC: 309 break; 310 case TRAP_CHLD: 311 case TRAP_LWP: 312 si32->_reason._ptrace_state._pe_report_event = 313 si->_reason._ptrace_state._pe_report_event; 314 CTASSERT(sizeof(si32->_reason._ptrace_state._option._pe_other_pid) == 315 sizeof(si32->_reason._ptrace_state._option._pe_lwp)); 316 si32->_reason._ptrace_state._option._pe_other_pid = 317 si->_reason._ptrace_state._option._pe_other_pid; 318 break; 319 case TRAP_SCE: 320 case TRAP_SCX: 321 si32->_reason._syscall._sysnum = 322 si->_reason._syscall._sysnum; 323 si32->_reason._syscall._retval[0] = 324 si->_reason._syscall._retval[0]; 325 si32->_reason._syscall._retval[1] = 326 si->_reason._syscall._retval[1]; 327 si32->_reason._syscall._error = 328 si->_reason._syscall._error; 329 for (i = 0; 330 i < __arraycount(si->_reason._syscall._args); i++) 331 si32->_reason._syscall._args[i] = 332 si->_reason._syscall._args[i]; 333 break; 334 default: 335 goto fill_fault; 336 } 337 break; 338 case SIGALRM: 339 case SIGVTALRM: 340 case SIGPROF: 341 default: /* see sigqueue() and kill1() */ 342 fill_rt: 343 si32->_reason._rt._pid = si->_reason._rt._pid; 344 si32->_reason._rt._uid = si->_reason._rt._uid; 345 si32->_reason._rt._value.sival_int = 346 si->_reason._rt._value.sival_int; 347 break; 348 case SIGURG: 349 case SIGIO: 350 si32->_reason._poll._band = si->_reason._poll._band; 351 si32->_reason._poll._fd = si->_reason._poll._fd; 352 break; 353 case SIGCHLD: 354 si32->_reason._child._pid = si->_reason._child._pid; 355 si32->_reason._child._uid = si->_reason._child._uid; 356 si32->_reason._child._status = si->_reason._child._status; 357 si32->_reason._child._utime = si->_reason._child._utime; 358 si32->_reason._child._stime = si->_reason._child._stime; 359 break; 360 } 361 } 362 363 void 364 netbsd32_si_to_si32(siginfo32_t *si32, const siginfo_t *si) 365 { 366 367 memset(si32, 0, sizeof (*si32)); 368 netbsd32_ksi_to_ksi32(&si32->_info, &si->_info); 369 } 370 371 void 372 getucontext32(struct lwp *l, ucontext32_t *ucp) 373 { 374 struct proc *p = l->l_proc; 375 376 KASSERT(mutex_owned(p->p_lock)); 377 378 ucp->uc_flags = 0; 379 ucp->uc_link = (uint32_t)(intptr_t)l->l_ctxlink; 380 ucp->uc_sigmask = l->l_sigmask; 381 ucp->uc_flags |= _UC_SIGMASK; 382 383 /* 384 * The (unsupplied) definition of the `current execution stack' 385 * in the System V Interface Definition appears to allow returning 386 * the main context stack. 387 */ 388 if ((l->l_sigstk.ss_flags & SS_ONSTACK) == 0) { 389 ucp->uc_stack.ss_sp = USRSTACK32; 390 ucp->uc_stack.ss_size = ctob(p->p_vmspace->vm_ssize); 391 ucp->uc_stack.ss_flags = 0; /* XXX, def. is Very Fishy */ 392 } else { 393 /* Simply copy alternate signal execution stack. */ 394 ucp->uc_stack.ss_sp = 395 (uint32_t)(intptr_t)l->l_sigstk.ss_sp; 396 ucp->uc_stack.ss_size = l->l_sigstk.ss_size; 397 ucp->uc_stack.ss_flags = l->l_sigstk.ss_flags; 398 } 399 ucp->uc_flags |= _UC_STACK; 400 mutex_exit(p->p_lock); 401 cpu_getmcontext32(l, &ucp->uc_mcontext, &ucp->uc_flags); 402 mutex_enter(p->p_lock); 403 } 404 405 int 406 netbsd32_getcontext(struct lwp *l, const struct netbsd32_getcontext_args *uap, register_t *retval) 407 { 408 /* { 409 syscallarg(netbsd32_ucontextp) ucp; 410 } */ 411 struct proc *p = l->l_proc; 412 ucontext32_t uc; 413 414 memset(&uc, 0, sizeof(uc)); 415 416 mutex_enter(p->p_lock); 417 getucontext32(l, &uc); 418 mutex_exit(p->p_lock); 419 420 return copyout(&uc, SCARG_P32(uap, ucp), sizeof (ucontext32_t)); 421 } 422 423 int 424 setucontext32(struct lwp *l, const ucontext32_t *ucp) 425 { 426 struct proc *p = l->l_proc; 427 int error; 428 429 KASSERT(mutex_owned(p->p_lock)); 430 431 if ((ucp->uc_flags & _UC_SIGMASK) != 0) { 432 error = sigprocmask1(l, SIG_SETMASK, &ucp->uc_sigmask, NULL); 433 if (error != 0) 434 return error; 435 } 436 437 mutex_exit(p->p_lock); 438 error = cpu_setmcontext32(l, &ucp->uc_mcontext, ucp->uc_flags); 439 mutex_enter(p->p_lock); 440 if (error != 0) 441 return error; 442 443 l->l_ctxlink = (void *)(intptr_t)ucp->uc_link; 444 445 /* 446 * If there was stack information, update whether or not we are 447 * still running on an alternate signal stack. 448 */ 449 if ((ucp->uc_flags & _UC_STACK) != 0) { 450 if (ucp->uc_stack.ss_flags & SS_ONSTACK) 451 l->l_sigstk.ss_flags |= SS_ONSTACK; 452 else 453 l->l_sigstk.ss_flags &= ~SS_ONSTACK; 454 } 455 456 return 0; 457 } 458 459 /* ARGSUSED */ 460 int 461 netbsd32_setcontext(struct lwp *l, const struct netbsd32_setcontext_args *uap, register_t *retval) 462 { 463 /* { 464 syscallarg(netbsd32_ucontextp) ucp; 465 } */ 466 ucontext32_t uc; 467 int error; 468 struct proc *p = l->l_proc; 469 470 error = copyin(SCARG_P32(uap, ucp), &uc, sizeof (uc)); 471 if (error) 472 return error; 473 if (!(uc.uc_flags & _UC_CPU)) 474 return EINVAL; 475 mutex_enter(p->p_lock); 476 error = setucontext32(l, &uc); 477 mutex_exit(p->p_lock); 478 if (error) 479 return error; 480 481 return EJUSTRETURN; 482 } 483 484 static int 485 netbsd32_sigtimedwait_put_info(const void *src, void *dst, size_t size) 486 { 487 const siginfo_t *info = src; 488 siginfo32_t info32; 489 490 netbsd32_si_to_si32(&info32, info); 491 492 return copyout(&info32, dst, sizeof(info32)); 493 } 494 495 static int 496 netbsd32_sigtimedwait_fetch_timeout(const void *src, void *dst, size_t size) 497 { 498 struct timespec *ts = dst; 499 struct netbsd32_timespec ts32; 500 int error; 501 502 error = copyin(src, &ts32, sizeof(ts32)); 503 if (error) 504 return error; 505 506 netbsd32_to_timespec(&ts32, ts); 507 return 0; 508 } 509 510 static int 511 netbsd32_sigtimedwait_put_timeout(const void *src, void *dst, size_t size) 512 { 513 const struct timespec *ts = src; 514 struct netbsd32_timespec ts32; 515 516 netbsd32_from_timespec(ts, &ts32); 517 518 return copyout(&ts32, dst, sizeof(ts32)); 519 } 520 521 int 522 netbsd32_____sigtimedwait50(struct lwp *l, const struct netbsd32_____sigtimedwait50_args *uap, register_t *retval) 523 { 524 /* { 525 syscallarg(netbsd32_sigsetp_t) set; 526 syscallarg(netbsd32_siginfop_t) info; 527 syscallarg(netbsd32_timespec50p_t) timeout; 528 } */ 529 struct sys_____sigtimedwait50_args ua; 530 531 NETBSD32TOP_UAP(set, const sigset_t); 532 NETBSD32TOP_UAP(info, siginfo_t); 533 NETBSD32TOP_UAP(timeout, struct timespec); 534 535 return sigtimedwait1(l, &ua, retval, 536 copyin, 537 netbsd32_sigtimedwait_put_info, 538 netbsd32_sigtimedwait_fetch_timeout, 539 netbsd32_sigtimedwait_put_timeout); 540 } 541 542 int 543 netbsd32_sigqueueinfo(struct lwp *l, 544 const struct netbsd32_sigqueueinfo_args *uap, register_t *retval) 545 { 546 /* { 547 syscallarg(pid_t) pid; 548 syscallarg(const netbsd32_siginfop_t) info; 549 } */ 550 struct __ksiginfo32 ksi32; 551 ksiginfo_t ksi; 552 int error; 553 554 if ((error = copyin(SCARG_P32(uap, info), &ksi32, 555 sizeof(ksi32))) != 0) 556 return error; 557 558 KSI_INIT(&ksi); 559 netbsd32_ksi32_to_ksi(&ksi.ksi_info, &ksi32); 560 561 return kill1(l, SCARG(uap, pid), &ksi, retval); 562 } 563 564 struct netbsd32_ktr_psig { 565 int signo; 566 netbsd32_pointer_t action; 567 sigset_t mask; 568 int code; 569 /* and optional siginfo_t */ 570 }; 571 572 #ifdef notyet 573 #ifdef KTRACE 574 void 575 netbsd32_ktrpsig(int sig, sig_t action, const sigset_t *mask, 576 const ksiginfo_t *ksi) 577 { 578 struct ktrace_entry *kte; 579 lwp_t *l = curlwp; 580 struct { 581 struct netbsd32_ktr_psig kp; 582 siginfo32_t si; 583 } *kbuf; 584 585 if (!KTRPOINT(l->l_proc, KTR_PSIG)) 586 return; 587 588 if (ktealloc(&kte, (void *)&kbuf, l, KTR_PSIG, sizeof(*kbuf))) 589 return; 590 591 kbuf->kp.signo = (char)sig; 592 NETBSD32PTR32(kbuf->kp.action, action); 593 kbuf->kp.mask = *mask; 594 595 if (ksi) { 596 kbuf->kp.code = KSI_TRAPCODE(ksi); 597 (void)memset(&kbuf->si, 0, sizeof(kbuf->si)); 598 netbsd32_ksi_to_ksi32(&kbuf->si._info, &ksi->ksi_info); 599 ktesethdrlen(kte, sizeof(*kbuf)); 600 } else { 601 kbuf->kp.code = 0; 602 ktesethdrlen(kte, sizeof(struct netbsd32_ktr_psig)); 603 } 604 605 ktraddentry(l, kte, KTA_WAITOK); 606 } 607 #endif 608 #endif 609