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