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