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