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