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