1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 1994-1995 Søren Schmidt 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 AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, 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 __FBSDID("$FreeBSD$"); 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 58 static int linux_do_tkill(struct thread *td, struct thread *tdt, 59 ksiginfo_t *ksi); 60 static void sicode_to_lsicode(int si_code, int *lsi_code); 61 62 static void 63 linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa) 64 { 65 unsigned long flags; 66 67 linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask); 68 bsa->sa_handler = PTRIN(lsa->lsa_handler); 69 bsa->sa_flags = 0; 70 71 flags = lsa->lsa_flags; 72 if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) { 73 flags &= ~LINUX_SA_NOCLDSTOP; 74 bsa->sa_flags |= SA_NOCLDSTOP; 75 } 76 if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) { 77 flags &= ~LINUX_SA_NOCLDWAIT; 78 bsa->sa_flags |= SA_NOCLDWAIT; 79 } 80 if (lsa->lsa_flags & LINUX_SA_SIGINFO) { 81 flags &= ~LINUX_SA_SIGINFO; 82 bsa->sa_flags |= SA_SIGINFO; 83 #ifdef notyet 84 /* 85 * XXX: We seem to be missing code to convert 86 * some of the fields in ucontext_t. 87 */ 88 linux_msg(curthread, 89 "partially unsupported sigaction flag SA_SIGINFO"); 90 #endif 91 } 92 if (lsa->lsa_flags & LINUX_SA_RESTORER) { 93 flags &= ~LINUX_SA_RESTORER; 94 /* 95 * We ignore the lsa_restorer and always use our own signal 96 * trampoline instead. It looks like SA_RESTORER is obsolete 97 * in Linux too - it doesn't seem to be used at all on arm64. 98 * In any case: see Linux sigreturn(2). 99 */ 100 } 101 if (lsa->lsa_flags & LINUX_SA_ONSTACK) { 102 flags &= ~LINUX_SA_ONSTACK; 103 bsa->sa_flags |= SA_ONSTACK; 104 } 105 if (lsa->lsa_flags & LINUX_SA_RESTART) { 106 flags &= ~LINUX_SA_RESTART; 107 bsa->sa_flags |= SA_RESTART; 108 } 109 if (lsa->lsa_flags & LINUX_SA_INTERRUPT) { 110 flags &= ~LINUX_SA_INTERRUPT; 111 /* Documented to be a "historical no-op". */ 112 } 113 if (lsa->lsa_flags & LINUX_SA_ONESHOT) { 114 flags &= ~LINUX_SA_ONESHOT; 115 bsa->sa_flags |= SA_RESETHAND; 116 } 117 if (lsa->lsa_flags & LINUX_SA_NOMASK) { 118 flags &= ~LINUX_SA_NOMASK; 119 bsa->sa_flags |= SA_NODEFER; 120 } 121 122 if (flags != 0) 123 linux_msg(curthread, "unsupported sigaction flag %#lx", flags); 124 } 125 126 static void 127 bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa) 128 { 129 130 bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask); 131 #ifdef COMPAT_LINUX32 132 lsa->lsa_handler = (uintptr_t)bsa->sa_handler; 133 #else 134 lsa->lsa_handler = bsa->sa_handler; 135 #endif 136 lsa->lsa_restorer = 0; /* unsupported */ 137 lsa->lsa_flags = 0; 138 if (bsa->sa_flags & SA_NOCLDSTOP) 139 lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; 140 if (bsa->sa_flags & SA_NOCLDWAIT) 141 lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; 142 if (bsa->sa_flags & SA_SIGINFO) 143 lsa->lsa_flags |= LINUX_SA_SIGINFO; 144 if (bsa->sa_flags & SA_ONSTACK) 145 lsa->lsa_flags |= LINUX_SA_ONSTACK; 146 if (bsa->sa_flags & SA_RESTART) 147 lsa->lsa_flags |= LINUX_SA_RESTART; 148 if (bsa->sa_flags & SA_RESETHAND) 149 lsa->lsa_flags |= LINUX_SA_ONESHOT; 150 if (bsa->sa_flags & SA_NODEFER) 151 lsa->lsa_flags |= LINUX_SA_NOMASK; 152 } 153 154 int 155 linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa, 156 l_sigaction_t *linux_osa) 157 { 158 struct sigaction act, oact, *nsa, *osa; 159 int error, sig; 160 161 if (!LINUX_SIG_VALID(linux_sig)) 162 return (EINVAL); 163 164 osa = (linux_osa != NULL) ? &oact : NULL; 165 if (linux_nsa != NULL) { 166 nsa = &act; 167 linux_to_bsd_sigaction(linux_nsa, nsa); 168 } else 169 nsa = NULL; 170 sig = linux_to_bsd_signal(linux_sig); 171 172 error = kern_sigaction(td, sig, nsa, osa, 0); 173 if (error) 174 return (error); 175 176 if (linux_osa != NULL) 177 bsd_to_linux_sigaction(osa, linux_osa); 178 179 return (0); 180 } 181 182 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 183 int 184 linux_signal(struct thread *td, struct linux_signal_args *args) 185 { 186 l_sigaction_t nsa, osa; 187 int error; 188 189 nsa.lsa_handler = args->handler; 190 nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; 191 LINUX_SIGEMPTYSET(nsa.lsa_mask); 192 193 error = linux_do_sigaction(td, args->sig, &nsa, &osa); 194 td->td_retval[0] = (int)(intptr_t)osa.lsa_handler; 195 196 return (error); 197 } 198 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 199 200 int 201 linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args) 202 { 203 l_sigaction_t nsa, osa; 204 int error; 205 206 if (args->sigsetsize != sizeof(l_sigset_t)) 207 return (EINVAL); 208 209 if (args->act != NULL) { 210 error = copyin(args->act, &nsa, sizeof(l_sigaction_t)); 211 if (error) 212 return (error); 213 } 214 215 error = linux_do_sigaction(td, args->sig, 216 args->act ? &nsa : NULL, 217 args->oact ? &osa : NULL); 218 219 if (args->oact != NULL && !error) { 220 error = copyout(&osa, args->oact, sizeof(l_sigaction_t)); 221 } 222 223 return (error); 224 } 225 226 static int 227 linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new, 228 l_sigset_t *old) 229 { 230 sigset_t omask, nmask; 231 sigset_t *nmaskp; 232 int error; 233 234 td->td_retval[0] = 0; 235 236 switch (how) { 237 case LINUX_SIG_BLOCK: 238 how = SIG_BLOCK; 239 break; 240 case LINUX_SIG_UNBLOCK: 241 how = SIG_UNBLOCK; 242 break; 243 case LINUX_SIG_SETMASK: 244 how = SIG_SETMASK; 245 break; 246 default: 247 return (EINVAL); 248 } 249 if (new != NULL) { 250 linux_to_bsd_sigset(new, &nmask); 251 nmaskp = &nmask; 252 } else 253 nmaskp = NULL; 254 error = kern_sigprocmask(td, how, nmaskp, &omask, 0); 255 if (error == 0 && old != NULL) 256 bsd_to_linux_sigset(&omask, old); 257 258 return (error); 259 } 260 261 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 262 int 263 linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args) 264 { 265 l_osigset_t mask; 266 l_sigset_t set, oset; 267 int error; 268 269 if (args->mask != NULL) { 270 error = copyin(args->mask, &mask, sizeof(l_osigset_t)); 271 if (error) 272 return (error); 273 LINUX_SIGEMPTYSET(set); 274 set.__mask = mask; 275 } 276 277 error = linux_do_sigprocmask(td, args->how, 278 args->mask ? &set : NULL, 279 args->omask ? &oset : NULL); 280 281 if (args->omask != NULL && !error) { 282 mask = oset.__mask; 283 error = copyout(&mask, args->omask, sizeof(l_osigset_t)); 284 } 285 286 return (error); 287 } 288 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 289 290 int 291 linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args) 292 { 293 l_sigset_t set, oset; 294 int error; 295 296 if (args->sigsetsize != sizeof(l_sigset_t)) 297 return (EINVAL); 298 299 if (args->mask != NULL) { 300 error = copyin(args->mask, &set, sizeof(l_sigset_t)); 301 if (error) 302 return (error); 303 } 304 305 error = linux_do_sigprocmask(td, args->how, 306 args->mask ? &set : NULL, 307 args->omask ? &oset : NULL); 308 309 if (args->omask != NULL && !error) { 310 error = copyout(&oset, args->omask, sizeof(l_sigset_t)); 311 } 312 313 return (error); 314 } 315 316 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 317 int 318 linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args) 319 { 320 struct proc *p = td->td_proc; 321 l_sigset_t mask; 322 323 PROC_LOCK(p); 324 bsd_to_linux_sigset(&td->td_sigmask, &mask); 325 PROC_UNLOCK(p); 326 td->td_retval[0] = mask.__mask; 327 return (0); 328 } 329 330 int 331 linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args) 332 { 333 struct proc *p = td->td_proc; 334 l_sigset_t lset; 335 sigset_t bset; 336 337 PROC_LOCK(p); 338 bsd_to_linux_sigset(&td->td_sigmask, &lset); 339 td->td_retval[0] = lset.__mask; 340 LINUX_SIGEMPTYSET(lset); 341 lset.__mask = args->mask; 342 linux_to_bsd_sigset(&lset, &bset); 343 td->td_sigmask = bset; 344 SIG_CANTMASK(td->td_sigmask); 345 signotify(td); 346 PROC_UNLOCK(p); 347 return (0); 348 } 349 350 int 351 linux_sigpending(struct thread *td, struct linux_sigpending_args *args) 352 { 353 struct proc *p = td->td_proc; 354 sigset_t bset; 355 l_sigset_t lset; 356 l_osigset_t mask; 357 358 PROC_LOCK(p); 359 bset = p->p_siglist; 360 SIGSETOR(bset, td->td_siglist); 361 SIGSETAND(bset, td->td_sigmask); 362 PROC_UNLOCK(p); 363 bsd_to_linux_sigset(&bset, &lset); 364 mask = lset.__mask; 365 return (copyout(&mask, args->mask, sizeof(mask))); 366 } 367 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 368 369 /* 370 * MPSAFE 371 */ 372 int 373 linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args) 374 { 375 struct proc *p = td->td_proc; 376 sigset_t bset; 377 l_sigset_t lset; 378 379 if (args->sigsetsize > sizeof(lset)) 380 return (EINVAL); 381 /* NOT REACHED */ 382 383 PROC_LOCK(p); 384 bset = p->p_siglist; 385 SIGSETOR(bset, td->td_siglist); 386 SIGSETAND(bset, td->td_sigmask); 387 PROC_UNLOCK(p); 388 bsd_to_linux_sigset(&bset, &lset); 389 return (copyout(&lset, args->set, args->sigsetsize)); 390 } 391 392 /* 393 * MPSAFE 394 */ 395 int 396 linux_rt_sigtimedwait(struct thread *td, 397 struct linux_rt_sigtimedwait_args *args) 398 { 399 int error, sig; 400 l_timeval ltv; 401 struct timeval tv; 402 struct timespec ts, *tsa; 403 l_sigset_t lset; 404 sigset_t bset; 405 l_siginfo_t linfo; 406 ksiginfo_t info; 407 408 if (args->sigsetsize != sizeof(l_sigset_t)) 409 return (EINVAL); 410 411 if ((error = copyin(args->mask, &lset, sizeof(lset)))) 412 return (error); 413 linux_to_bsd_sigset(&lset, &bset); 414 415 tsa = NULL; 416 if (args->timeout) { 417 if ((error = copyin(args->timeout, <v, sizeof(ltv)))) 418 return (error); 419 tv.tv_sec = (long)ltv.tv_sec; 420 tv.tv_usec = (suseconds_t)ltv.tv_usec; 421 if (itimerfix(&tv)) { 422 /* 423 * The timeout was invalid. Convert it to something 424 * valid that will act as it does under Linux. 425 */ 426 tv.tv_sec += tv.tv_usec / 1000000; 427 tv.tv_usec %= 1000000; 428 if (tv.tv_usec < 0) { 429 tv.tv_sec -= 1; 430 tv.tv_usec += 1000000; 431 } 432 if (tv.tv_sec < 0) 433 timevalclear(&tv); 434 } 435 TIMEVAL_TO_TIMESPEC(&tv, &ts); 436 tsa = &ts; 437 } 438 error = kern_sigtimedwait(td, bset, &info, tsa); 439 if (error) 440 return (error); 441 442 sig = bsd_to_linux_signal(info.ksi_signo); 443 444 if (args->ptr) { 445 memset(&linfo, 0, sizeof(linfo)); 446 ksiginfo_to_lsiginfo(&info, &linfo, sig); 447 error = copyout(&linfo, args->ptr, sizeof(linfo)); 448 } 449 if (error == 0) 450 td->td_retval[0] = sig; 451 452 return (error); 453 } 454 455 int 456 linux_kill(struct thread *td, struct linux_kill_args *args) 457 { 458 int l_signum; 459 460 /* 461 * Allow signal 0 as a means to check for privileges 462 */ 463 if (!LINUX_SIG_VALID(args->signum) && args->signum != 0) 464 return (EINVAL); 465 466 if (args->signum > 0) 467 l_signum = linux_to_bsd_signal(args->signum); 468 else 469 l_signum = 0; 470 471 return (kern_kill(td, args->pid, l_signum)); 472 } 473 474 static int 475 linux_do_tkill(struct thread *td, struct thread *tdt, ksiginfo_t *ksi) 476 { 477 struct proc *p; 478 int error; 479 480 p = tdt->td_proc; 481 AUDIT_ARG_SIGNUM(ksi->ksi_signo); 482 AUDIT_ARG_PID(p->p_pid); 483 AUDIT_ARG_PROCESS(p); 484 485 error = p_cansignal(td, p, ksi->ksi_signo); 486 if (error != 0 || ksi->ksi_signo == 0) 487 goto out; 488 489 tdksignal(tdt, ksi->ksi_signo, ksi); 490 491 out: 492 PROC_UNLOCK(p); 493 return (error); 494 } 495 496 int 497 linux_tgkill(struct thread *td, struct linux_tgkill_args *args) 498 { 499 struct thread *tdt; 500 ksiginfo_t ksi; 501 int sig; 502 503 if (args->pid <= 0 || args->tgid <=0) 504 return (EINVAL); 505 506 /* 507 * Allow signal 0 as a means to check for privileges 508 */ 509 if (!LINUX_SIG_VALID(args->sig) && args->sig != 0) 510 return (EINVAL); 511 512 if (args->sig > 0) 513 sig = linux_to_bsd_signal(args->sig); 514 else 515 sig = 0; 516 517 tdt = linux_tdfind(td, args->pid, args->tgid); 518 if (tdt == NULL) 519 return (ESRCH); 520 521 ksiginfo_init(&ksi); 522 ksi.ksi_signo = sig; 523 ksi.ksi_code = SI_LWP; 524 ksi.ksi_errno = 0; 525 ksi.ksi_pid = td->td_proc->p_pid; 526 ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 527 return (linux_do_tkill(td, tdt, &ksi)); 528 } 529 530 /* 531 * Deprecated since 2.5.75. Replaced by tgkill(). 532 */ 533 int 534 linux_tkill(struct thread *td, struct linux_tkill_args *args) 535 { 536 struct thread *tdt; 537 ksiginfo_t ksi; 538 int sig; 539 540 if (args->tid <= 0) 541 return (EINVAL); 542 543 if (!LINUX_SIG_VALID(args->sig)) 544 return (EINVAL); 545 546 sig = linux_to_bsd_signal(args->sig); 547 548 tdt = linux_tdfind(td, args->tid, -1); 549 if (tdt == NULL) 550 return (ESRCH); 551 552 ksiginfo_init(&ksi); 553 ksi.ksi_signo = sig; 554 ksi.ksi_code = SI_LWP; 555 ksi.ksi_errno = 0; 556 ksi.ksi_pid = td->td_proc->p_pid; 557 ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 558 return (linux_do_tkill(td, tdt, &ksi)); 559 } 560 561 void 562 ksiginfo_to_lsiginfo(const ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig) 563 { 564 565 siginfo_to_lsiginfo(&ksi->ksi_info, lsi, sig); 566 } 567 568 static void 569 sicode_to_lsicode(int si_code, int *lsi_code) 570 { 571 572 switch (si_code) { 573 case SI_USER: 574 *lsi_code = LINUX_SI_USER; 575 break; 576 case SI_KERNEL: 577 *lsi_code = LINUX_SI_KERNEL; 578 break; 579 case SI_QUEUE: 580 *lsi_code = LINUX_SI_QUEUE; 581 break; 582 case SI_TIMER: 583 *lsi_code = LINUX_SI_TIMER; 584 break; 585 case SI_MESGQ: 586 *lsi_code = LINUX_SI_MESGQ; 587 break; 588 case SI_ASYNCIO: 589 *lsi_code = LINUX_SI_ASYNCIO; 590 break; 591 case SI_LWP: 592 *lsi_code = LINUX_SI_TKILL; 593 break; 594 default: 595 *lsi_code = si_code; 596 break; 597 } 598 } 599 600 void 601 siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig) 602 { 603 604 /* sig alredy converted */ 605 lsi->lsi_signo = sig; 606 sicode_to_lsicode(si->si_code, &lsi->lsi_code); 607 608 switch (si->si_code) { 609 case SI_LWP: 610 lsi->lsi_pid = si->si_pid; 611 lsi->lsi_uid = si->si_uid; 612 break; 613 614 case SI_TIMER: 615 lsi->lsi_int = si->si_value.sival_int; 616 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 617 lsi->lsi_tid = si->si_timerid; 618 break; 619 620 case SI_QUEUE: 621 lsi->lsi_pid = si->si_pid; 622 lsi->lsi_uid = si->si_uid; 623 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 624 break; 625 626 case SI_ASYNCIO: 627 lsi->lsi_int = si->si_value.sival_int; 628 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 629 break; 630 631 default: 632 switch (sig) { 633 case LINUX_SIGPOLL: 634 /* XXX si_fd? */ 635 lsi->lsi_band = si->si_band; 636 break; 637 638 case LINUX_SIGCHLD: 639 lsi->lsi_errno = 0; 640 lsi->lsi_pid = si->si_pid; 641 lsi->lsi_uid = si->si_uid; 642 643 if (si->si_code == CLD_STOPPED || si->si_code == CLD_KILLED) 644 lsi->lsi_status = bsd_to_linux_signal(si->si_status); 645 else if (si->si_code == CLD_CONTINUED) 646 lsi->lsi_status = bsd_to_linux_signal(SIGCONT); 647 else 648 lsi->lsi_status = si->si_status; 649 break; 650 651 case LINUX_SIGBUS: 652 case LINUX_SIGILL: 653 case LINUX_SIGFPE: 654 case LINUX_SIGSEGV: 655 lsi->lsi_addr = PTROUT(si->si_addr); 656 break; 657 658 default: 659 lsi->lsi_pid = si->si_pid; 660 lsi->lsi_uid = si->si_uid; 661 if (sig >= LINUX_SIGRTMIN) { 662 lsi->lsi_int = si->si_value.sival_int; 663 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 664 } 665 break; 666 } 667 break; 668 } 669 } 670 671 void 672 lsiginfo_to_ksiginfo(const l_siginfo_t *lsi, ksiginfo_t *ksi, int sig) 673 { 674 675 ksi->ksi_signo = sig; 676 ksi->ksi_code = lsi->lsi_code; /* XXX. Convert. */ 677 ksi->ksi_pid = lsi->lsi_pid; 678 ksi->ksi_uid = lsi->lsi_uid; 679 ksi->ksi_status = lsi->lsi_status; 680 ksi->ksi_addr = PTRIN(lsi->lsi_addr); 681 ksi->ksi_info.si_value.sival_int = lsi->lsi_int; 682 } 683 684 int 685 linux_rt_sigqueueinfo(struct thread *td, struct linux_rt_sigqueueinfo_args *args) 686 { 687 l_siginfo_t linfo; 688 struct proc *p; 689 ksiginfo_t ksi; 690 int error; 691 int sig; 692 693 if (!LINUX_SIG_VALID(args->sig)) 694 return (EINVAL); 695 696 error = copyin(args->info, &linfo, sizeof(linfo)); 697 if (error != 0) 698 return (error); 699 700 if (linfo.lsi_code >= 0) 701 return (EPERM); 702 703 sig = linux_to_bsd_signal(args->sig); 704 705 error = ESRCH; 706 if ((p = pfind_any(args->pid)) != NULL) { 707 error = p_cansignal(td, p, sig); 708 if (error != 0) { 709 PROC_UNLOCK(p); 710 return (error); 711 } 712 713 ksiginfo_init(&ksi); 714 lsiginfo_to_ksiginfo(&linfo, &ksi, sig); 715 error = tdsendsignal(p, NULL, sig, &ksi); 716 PROC_UNLOCK(p); 717 } 718 719 return (error); 720 } 721 722 int 723 linux_rt_tgsigqueueinfo(struct thread *td, struct linux_rt_tgsigqueueinfo_args *args) 724 { 725 l_siginfo_t linfo; 726 struct thread *tds; 727 ksiginfo_t ksi; 728 int error; 729 int sig; 730 731 if (!LINUX_SIG_VALID(args->sig)) 732 return (EINVAL); 733 734 error = copyin(args->uinfo, &linfo, sizeof(linfo)); 735 if (error != 0) 736 return (error); 737 738 if (linfo.lsi_code >= 0) 739 return (EPERM); 740 741 tds = linux_tdfind(td, args->tid, args->tgid); 742 if (tds == NULL) 743 return (ESRCH); 744 745 sig = linux_to_bsd_signal(args->sig); 746 ksiginfo_init(&ksi); 747 lsiginfo_to_ksiginfo(&linfo, &ksi, sig); 748 return (linux_do_tkill(td, tds, &ksi)); 749 } 750 751 int 752 linux_rt_sigsuspend(struct thread *td, struct linux_rt_sigsuspend_args *uap) 753 { 754 l_sigset_t lmask; 755 sigset_t sigmask; 756 int error; 757 758 if (uap->sigsetsize != sizeof(l_sigset_t)) 759 return (EINVAL); 760 761 error = copyin(uap->newset, &lmask, sizeof(l_sigset_t)); 762 if (error != 0) 763 return (error); 764 765 linux_to_bsd_sigset(&lmask, &sigmask); 766 return (kern_sigsuspend(td, sigmask)); 767 } 768