linux_signal.c revision 293493
1/*- 2 * Copyright (c) 1994-1995 S��ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 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 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD: stable/10/sys/compat/linux/linux_signal.c 293493 2016-01-09 15:16:13Z dchagin $"); 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/lock.h> 35#include <sys/mutex.h> 36#include <sys/sx.h> 37#include <sys/proc.h> 38#include <sys/signalvar.h> 39#include <sys/syscallsubr.h> 40#include <sys/sysproto.h> 41 42#include <security/audit/audit.h> 43 44#include "opt_compat.h" 45 46#ifdef COMPAT_LINUX32 47#include <machine/../linux32/linux.h> 48#include <machine/../linux32/linux32_proto.h> 49#else 50#include <machine/../linux/linux.h> 51#include <machine/../linux/linux_proto.h> 52#endif 53#include <compat/linux/linux_signal.h> 54#include <compat/linux/linux_util.h> 55#include <compat/linux/linux_emul.h> 56#include <compat/linux/linux_misc.h> 57 58static int linux_do_tkill(struct thread *td, struct thread *tdt, 59 ksiginfo_t *ksi); 60 61void 62linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss) 63{ 64 int b, l; 65 66 SIGEMPTYSET(*bss); 67 bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); 68 bss->__bits[1] = lss->__bits[1]; 69 for (l = 1; l <= LINUX_SIGTBLSZ; l++) { 70 if (LINUX_SIGISMEMBER(*lss, l)) { 71 b = linux_to_bsd_signal[_SIG_IDX(l)]; 72 if (b) 73 SIGADDSET(*bss, b); 74 } 75 } 76} 77 78void 79bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss) 80{ 81 int b, l; 82 83 LINUX_SIGEMPTYSET(*lss); 84 lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); 85 lss->__bits[1] = bss->__bits[1]; 86 for (b = 1; b <= LINUX_SIGTBLSZ; b++) { 87 if (SIGISMEMBER(*bss, b)) { 88 l = bsd_to_linux_signal[_SIG_IDX(b)]; 89 if (l) 90 LINUX_SIGADDSET(*lss, l); 91 } 92 } 93} 94 95static void 96linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa) 97{ 98 99 linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask); 100 bsa->sa_handler = PTRIN(lsa->lsa_handler); 101 bsa->sa_flags = 0; 102 if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) 103 bsa->sa_flags |= SA_NOCLDSTOP; 104 if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) 105 bsa->sa_flags |= SA_NOCLDWAIT; 106 if (lsa->lsa_flags & LINUX_SA_SIGINFO) 107 bsa->sa_flags |= SA_SIGINFO; 108 if (lsa->lsa_flags & LINUX_SA_ONSTACK) 109 bsa->sa_flags |= SA_ONSTACK; 110 if (lsa->lsa_flags & LINUX_SA_RESTART) 111 bsa->sa_flags |= SA_RESTART; 112 if (lsa->lsa_flags & LINUX_SA_ONESHOT) 113 bsa->sa_flags |= SA_RESETHAND; 114 if (lsa->lsa_flags & LINUX_SA_NOMASK) 115 bsa->sa_flags |= SA_NODEFER; 116} 117 118static void 119bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa) 120{ 121 122 bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask); 123#ifdef COMPAT_LINUX32 124 lsa->lsa_handler = (uintptr_t)bsa->sa_handler; 125#else 126 lsa->lsa_handler = bsa->sa_handler; 127#endif 128 lsa->lsa_restorer = 0; /* unsupported */ 129 lsa->lsa_flags = 0; 130 if (bsa->sa_flags & SA_NOCLDSTOP) 131 lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; 132 if (bsa->sa_flags & SA_NOCLDWAIT) 133 lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; 134 if (bsa->sa_flags & SA_SIGINFO) 135 lsa->lsa_flags |= LINUX_SA_SIGINFO; 136 if (bsa->sa_flags & SA_ONSTACK) 137 lsa->lsa_flags |= LINUX_SA_ONSTACK; 138 if (bsa->sa_flags & SA_RESTART) 139 lsa->lsa_flags |= LINUX_SA_RESTART; 140 if (bsa->sa_flags & SA_RESETHAND) 141 lsa->lsa_flags |= LINUX_SA_ONESHOT; 142 if (bsa->sa_flags & SA_NODEFER) 143 lsa->lsa_flags |= LINUX_SA_NOMASK; 144} 145 146int 147linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa, 148 l_sigaction_t *linux_osa) 149{ 150 struct sigaction act, oact, *nsa, *osa; 151 int error, sig; 152 153 if (!LINUX_SIG_VALID(linux_sig)) 154 return (EINVAL); 155 156 osa = (linux_osa != NULL) ? &oact : NULL; 157 if (linux_nsa != NULL) { 158 nsa = &act; 159 linux_to_bsd_sigaction(linux_nsa, nsa); 160 } else 161 nsa = NULL; 162 163 if (linux_sig <= LINUX_SIGTBLSZ) 164 sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)]; 165 else 166 sig = linux_sig; 167 168 error = kern_sigaction(td, sig, nsa, osa, 0); 169 if (error) 170 return (error); 171 172 if (linux_osa != NULL) 173 bsd_to_linux_sigaction(osa, linux_osa); 174 175 return (0); 176} 177 178 179int 180linux_signal(struct thread *td, struct linux_signal_args *args) 181{ 182 l_sigaction_t nsa, osa; 183 int error; 184 185#ifdef DEBUG 186 if (ldebug(signal)) 187 printf(ARGS(signal, "%d, %p"), 188 args->sig, (void *)(uintptr_t)args->handler); 189#endif 190 191 nsa.lsa_handler = args->handler; 192 nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; 193 LINUX_SIGEMPTYSET(nsa.lsa_mask); 194 195 error = linux_do_sigaction(td, args->sig, &nsa, &osa); 196 td->td_retval[0] = (int)(intptr_t)osa.lsa_handler; 197 198 return (error); 199} 200 201int 202linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args) 203{ 204 l_sigaction_t nsa, osa; 205 int error; 206 207#ifdef DEBUG 208 if (ldebug(rt_sigaction)) 209 printf(ARGS(rt_sigaction, "%ld, %p, %p, %ld"), 210 (long)args->sig, (void *)args->act, 211 (void *)args->oact, (long)args->sigsetsize); 212#endif 213 214 if (args->sigsetsize != sizeof(l_sigset_t)) 215 return (EINVAL); 216 217 if (args->act != NULL) { 218 error = copyin(args->act, &nsa, sizeof(l_sigaction_t)); 219 if (error) 220 return (error); 221 } 222 223 error = linux_do_sigaction(td, args->sig, 224 args->act ? &nsa : NULL, 225 args->oact ? &osa : NULL); 226 227 if (args->oact != NULL && !error) { 228 error = copyout(&osa, args->oact, sizeof(l_sigaction_t)); 229 } 230 231 return (error); 232} 233 234static int 235linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new, 236 l_sigset_t *old) 237{ 238 sigset_t omask, nmask; 239 sigset_t *nmaskp; 240 int error; 241 242 td->td_retval[0] = 0; 243 244 switch (how) { 245 case LINUX_SIG_BLOCK: 246 how = SIG_BLOCK; 247 break; 248 case LINUX_SIG_UNBLOCK: 249 how = SIG_UNBLOCK; 250 break; 251 case LINUX_SIG_SETMASK: 252 how = SIG_SETMASK; 253 break; 254 default: 255 return (EINVAL); 256 } 257 if (new != NULL) { 258 linux_to_bsd_sigset(new, &nmask); 259 nmaskp = &nmask; 260 } else 261 nmaskp = NULL; 262 error = kern_sigprocmask(td, how, nmaskp, &omask, 0); 263 if (error == 0 && old != NULL) 264 bsd_to_linux_sigset(&omask, old); 265 266 return (error); 267} 268 269int 270linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args) 271{ 272 l_osigset_t mask; 273 l_sigset_t set, oset; 274 int error; 275 276#ifdef DEBUG 277 if (ldebug(sigprocmask)) 278 printf(ARGS(sigprocmask, "%d, *, *"), args->how); 279#endif 280 281 if (args->mask != NULL) { 282 error = copyin(args->mask, &mask, sizeof(l_osigset_t)); 283 if (error) 284 return (error); 285 LINUX_SIGEMPTYSET(set); 286 set.__bits[0] = mask; 287 } 288 289 error = linux_do_sigprocmask(td, args->how, 290 args->mask ? &set : NULL, 291 args->omask ? &oset : NULL); 292 293 if (args->omask != NULL && !error) { 294 mask = oset.__bits[0]; 295 error = copyout(&mask, args->omask, sizeof(l_osigset_t)); 296 } 297 298 return (error); 299} 300 301int 302linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args) 303{ 304 l_sigset_t set, oset; 305 int error; 306 307#ifdef DEBUG 308 if (ldebug(rt_sigprocmask)) 309 printf(ARGS(rt_sigprocmask, "%d, %p, %p, %ld"), 310 args->how, (void *)args->mask, 311 (void *)args->omask, (long)args->sigsetsize); 312#endif 313 314 if (args->sigsetsize != sizeof(l_sigset_t)) 315 return EINVAL; 316 317 if (args->mask != NULL) { 318 error = copyin(args->mask, &set, sizeof(l_sigset_t)); 319 if (error) 320 return (error); 321 } 322 323 error = linux_do_sigprocmask(td, args->how, 324 args->mask ? &set : NULL, 325 args->omask ? &oset : NULL); 326 327 if (args->omask != NULL && !error) { 328 error = copyout(&oset, args->omask, sizeof(l_sigset_t)); 329 } 330 331 return (error); 332} 333 334int 335linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args) 336{ 337 struct proc *p = td->td_proc; 338 l_sigset_t mask; 339 340#ifdef DEBUG 341 if (ldebug(sgetmask)) 342 printf(ARGS(sgetmask, "")); 343#endif 344 345 PROC_LOCK(p); 346 bsd_to_linux_sigset(&td->td_sigmask, &mask); 347 PROC_UNLOCK(p); 348 td->td_retval[0] = mask.__bits[0]; 349 return (0); 350} 351 352int 353linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args) 354{ 355 struct proc *p = td->td_proc; 356 l_sigset_t lset; 357 sigset_t bset; 358 359#ifdef DEBUG 360 if (ldebug(ssetmask)) 361 printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask); 362#endif 363 364 PROC_LOCK(p); 365 bsd_to_linux_sigset(&td->td_sigmask, &lset); 366 td->td_retval[0] = lset.__bits[0]; 367 LINUX_SIGEMPTYSET(lset); 368 lset.__bits[0] = args->mask; 369 linux_to_bsd_sigset(&lset, &bset); 370 td->td_sigmask = bset; 371 SIG_CANTMASK(td->td_sigmask); 372 signotify(td); 373 PROC_UNLOCK(p); 374 return (0); 375} 376 377/* 378 * MPSAFE 379 */ 380int 381linux_sigpending(struct thread *td, struct linux_sigpending_args *args) 382{ 383 struct proc *p = td->td_proc; 384 sigset_t bset; 385 l_sigset_t lset; 386 l_osigset_t mask; 387 388#ifdef DEBUG 389 if (ldebug(sigpending)) 390 printf(ARGS(sigpending, "*")); 391#endif 392 393 PROC_LOCK(p); 394 bset = p->p_siglist; 395 SIGSETOR(bset, td->td_siglist); 396 SIGSETAND(bset, td->td_sigmask); 397 PROC_UNLOCK(p); 398 bsd_to_linux_sigset(&bset, &lset); 399 mask = lset.__bits[0]; 400 return (copyout(&mask, args->mask, sizeof(mask))); 401} 402 403/* 404 * MPSAFE 405 */ 406int 407linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args) 408{ 409 struct proc *p = td->td_proc; 410 sigset_t bset; 411 l_sigset_t lset; 412 413 if (args->sigsetsize > sizeof(lset)) 414 return EINVAL; 415 /* NOT REACHED */ 416 417#ifdef DEBUG 418 if (ldebug(rt_sigpending)) 419 printf(ARGS(rt_sigpending, "*")); 420#endif 421 422 PROC_LOCK(p); 423 bset = p->p_siglist; 424 SIGSETOR(bset, td->td_siglist); 425 SIGSETAND(bset, td->td_sigmask); 426 PROC_UNLOCK(p); 427 bsd_to_linux_sigset(&bset, &lset); 428 return (copyout(&lset, args->set, args->sigsetsize)); 429} 430 431/* 432 * MPSAFE 433 */ 434int 435linux_rt_sigtimedwait(struct thread *td, 436 struct linux_rt_sigtimedwait_args *args) 437{ 438 int error, sig; 439 l_timeval ltv; 440 struct timeval tv; 441 struct timespec ts, *tsa; 442 l_sigset_t lset; 443 sigset_t bset; 444 l_siginfo_t linfo; 445 ksiginfo_t info; 446 447#ifdef DEBUG 448 if (ldebug(rt_sigtimedwait)) 449 printf(ARGS(rt_sigtimedwait, "*")); 450#endif 451 if (args->sigsetsize != sizeof(l_sigset_t)) 452 return (EINVAL); 453 454 if ((error = copyin(args->mask, &lset, sizeof(lset)))) 455 return (error); 456 linux_to_bsd_sigset(&lset, &bset); 457 458 tsa = NULL; 459 if (args->timeout) { 460 if ((error = copyin(args->timeout, <v, sizeof(ltv)))) 461 return (error); 462#ifdef DEBUG 463 if (ldebug(rt_sigtimedwait)) 464 printf(LMSG("linux_rt_sigtimedwait: " 465 "incoming timeout (%d/%d)\n"), 466 ltv.tv_sec, ltv.tv_usec); 467#endif 468 tv.tv_sec = (long)ltv.tv_sec; 469 tv.tv_usec = (suseconds_t)ltv.tv_usec; 470 if (itimerfix(&tv)) { 471 /* 472 * The timeout was invalid. Convert it to something 473 * valid that will act as it does under Linux. 474 */ 475 tv.tv_sec += tv.tv_usec / 1000000; 476 tv.tv_usec %= 1000000; 477 if (tv.tv_usec < 0) { 478 tv.tv_sec -= 1; 479 tv.tv_usec += 1000000; 480 } 481 if (tv.tv_sec < 0) 482 timevalclear(&tv); 483#ifdef DEBUG 484 if (ldebug(rt_sigtimedwait)) 485 printf(LMSG("linux_rt_sigtimedwait: " 486 "converted timeout (%jd/%ld)\n"), 487 (intmax_t)tv.tv_sec, tv.tv_usec); 488#endif 489 } 490 TIMEVAL_TO_TIMESPEC(&tv, &ts); 491 tsa = &ts; 492 } 493 error = kern_sigtimedwait(td, bset, &info, tsa); 494#ifdef DEBUG 495 if (ldebug(rt_sigtimedwait)) 496 printf(LMSG("linux_rt_sigtimedwait: " 497 "sigtimedwait returning (%d)\n"), error); 498#endif 499 if (error) 500 return (error); 501 502 sig = BSD_TO_LINUX_SIGNAL(info.ksi_signo); 503 504 if (args->ptr) { 505 memset(&linfo, 0, sizeof(linfo)); 506 ksiginfo_to_lsiginfo(&info, &linfo, sig); 507 error = copyout(&linfo, args->ptr, sizeof(linfo)); 508 } 509 if (error == 0) 510 td->td_retval[0] = sig; 511 512 return (error); 513} 514 515int 516linux_kill(struct thread *td, struct linux_kill_args *args) 517{ 518 struct kill_args /* { 519 int pid; 520 int signum; 521 } */ tmp; 522 523#ifdef DEBUG 524 if (ldebug(kill)) 525 printf(ARGS(kill, "%d, %d"), args->pid, args->signum); 526#endif 527 528 /* 529 * Allow signal 0 as a means to check for privileges 530 */ 531 if (!LINUX_SIG_VALID(args->signum) && args->signum != 0) 532 return (EINVAL); 533 534 if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ) 535 tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)]; 536 else 537 tmp.signum = args->signum; 538 539 tmp.pid = args->pid; 540 return (sys_kill(td, &tmp)); 541} 542 543static int 544linux_do_tkill(struct thread *td, struct thread *tdt, ksiginfo_t *ksi) 545{ 546 struct proc *p; 547 int error; 548 549 p = tdt->td_proc; 550 AUDIT_ARG_SIGNUM(ksi->ksi_signo); 551 AUDIT_ARG_PID(p->p_pid); 552 AUDIT_ARG_PROCESS(p); 553 554 error = p_cansignal(td, p, ksi->ksi_signo); 555 if (error != 0 || ksi->ksi_signo == 0) 556 goto out; 557 558 tdksignal(tdt, ksi->ksi_signo, ksi); 559 560out: 561 PROC_UNLOCK(p); 562 return (error); 563} 564 565int 566linux_tgkill(struct thread *td, struct linux_tgkill_args *args) 567{ 568 struct thread *tdt; 569 ksiginfo_t ksi; 570 int sig; 571 572#ifdef DEBUG 573 if (ldebug(tgkill)) 574 printf(ARGS(tgkill, "%d, %d, %d"), 575 args->tgid, args->pid, args->sig); 576#endif 577 578 if (args->pid <= 0 || args->tgid <=0) 579 return (EINVAL); 580 581 /* 582 * Allow signal 0 as a means to check for privileges 583 */ 584 if (!LINUX_SIG_VALID(args->sig) && args->sig != 0) 585 return (EINVAL); 586 587 if (args->sig > 0 && args->sig <= LINUX_SIGTBLSZ) 588 sig = linux_to_bsd_signal[_SIG_IDX(args->sig)]; 589 else 590 sig = args->sig; 591 592 tdt = linux_tdfind(td, args->pid, args->tgid); 593 if (tdt == NULL) 594 return (ESRCH); 595 596 ksiginfo_init(&ksi); 597 ksi.ksi_signo = sig; 598 ksi.ksi_code = LINUX_SI_TKILL; 599 ksi.ksi_errno = 0; 600 ksi.ksi_pid = td->td_proc->p_pid; 601 ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 602 return (linux_do_tkill(td, tdt, &ksi)); 603} 604 605/* 606 * Deprecated since 2.5.75. Replaced by tgkill(). 607 */ 608int 609linux_tkill(struct thread *td, struct linux_tkill_args *args) 610{ 611 struct thread *tdt; 612 ksiginfo_t ksi; 613 int sig; 614 615#ifdef DEBUG 616 if (ldebug(tkill)) 617 printf(ARGS(tkill, "%i, %i"), args->tid, args->sig); 618#endif 619 if (args->tid <= 0) 620 return (EINVAL); 621 622 if (!LINUX_SIG_VALID(args->sig)) 623 return (EINVAL); 624 625 if (args->sig > 0 && args->sig <= LINUX_SIGTBLSZ) 626 sig = linux_to_bsd_signal[_SIG_IDX(args->sig)]; 627 else 628 sig = args->sig; 629 630 tdt = linux_tdfind(td, args->tid, -1); 631 if (tdt == NULL) 632 return (ESRCH); 633 634 ksiginfo_init(&ksi); 635 ksi.ksi_signo = sig; 636 ksi.ksi_code = LINUX_SI_TKILL; 637 ksi.ksi_errno = 0; 638 ksi.ksi_pid = td->td_proc->p_pid; 639 ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 640 return (linux_do_tkill(td, tdt, &ksi)); 641} 642 643void 644ksiginfo_to_lsiginfo(ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig) 645{ 646 647 lsi->lsi_signo = sig; 648 lsi->lsi_code = ksi->ksi_code; 649 650 switch (sig) { 651 case LINUX_SIGPOLL: 652 /* XXX si_fd? */ 653 lsi->lsi_band = ksi->ksi_band; 654 break; 655 case LINUX_SIGCHLD: 656 lsi->lsi_pid = ksi->ksi_pid; 657 lsi->lsi_uid = ksi->ksi_uid; 658 lsi->lsi_status = ksi->ksi_status; 659 break; 660 case LINUX_SIGBUS: 661 case LINUX_SIGILL: 662 case LINUX_SIGFPE: 663 case LINUX_SIGSEGV: 664 lsi->lsi_addr = PTROUT(ksi->ksi_addr); 665 break; 666 default: 667 /* XXX SI_TIMER etc... */ 668 lsi->lsi_pid = ksi->ksi_pid; 669 lsi->lsi_uid = ksi->ksi_uid; 670 break; 671 } 672 if (sig >= LINUX_SIGRTMIN) { 673 lsi->lsi_int = ksi->ksi_info.si_value.sival_int; 674 lsi->lsi_ptr = PTROUT(ksi->ksi_info.si_value.sival_ptr); 675 } 676} 677