1 /*- 2 * SPDX-License-Identifier: BSD-3-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 * in this position and unchanged. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/lock.h> 37 #include <sys/mutex.h> 38 #include <sys/sx.h> 39 #include <sys/proc.h> 40 #include <sys/signalvar.h> 41 #include <sys/syscallsubr.h> 42 #include <sys/sysproto.h> 43 44 #include <security/audit/audit.h> 45 46 #include "opt_compat.h" 47 48 #ifdef COMPAT_LINUX32 49 #include <machine/../linux32/linux.h> 50 #include <machine/../linux32/linux32_proto.h> 51 #else 52 #include <machine/../linux/linux.h> 53 #include <machine/../linux/linux_proto.h> 54 #endif 55 #include <compat/linux/linux_signal.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 64 65 static void 66 linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa) 67 { 68 69 linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask); 70 bsa->sa_handler = PTRIN(lsa->lsa_handler); 71 bsa->sa_flags = 0; 72 if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) 73 bsa->sa_flags |= SA_NOCLDSTOP; 74 if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) 75 bsa->sa_flags |= SA_NOCLDWAIT; 76 if (lsa->lsa_flags & LINUX_SA_SIGINFO) 77 bsa->sa_flags |= SA_SIGINFO; 78 if (lsa->lsa_flags & LINUX_SA_ONSTACK) 79 bsa->sa_flags |= SA_ONSTACK; 80 if (lsa->lsa_flags & LINUX_SA_RESTART) 81 bsa->sa_flags |= SA_RESTART; 82 if (lsa->lsa_flags & LINUX_SA_ONESHOT) 83 bsa->sa_flags |= SA_RESETHAND; 84 if (lsa->lsa_flags & LINUX_SA_NOMASK) 85 bsa->sa_flags |= SA_NODEFER; 86 } 87 88 static void 89 bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa) 90 { 91 92 bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask); 93 #ifdef COMPAT_LINUX32 94 lsa->lsa_handler = (uintptr_t)bsa->sa_handler; 95 #else 96 lsa->lsa_handler = bsa->sa_handler; 97 #endif 98 lsa->lsa_restorer = 0; /* unsupported */ 99 lsa->lsa_flags = 0; 100 if (bsa->sa_flags & SA_NOCLDSTOP) 101 lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; 102 if (bsa->sa_flags & SA_NOCLDWAIT) 103 lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; 104 if (bsa->sa_flags & SA_SIGINFO) 105 lsa->lsa_flags |= LINUX_SA_SIGINFO; 106 if (bsa->sa_flags & SA_ONSTACK) 107 lsa->lsa_flags |= LINUX_SA_ONSTACK; 108 if (bsa->sa_flags & SA_RESTART) 109 lsa->lsa_flags |= LINUX_SA_RESTART; 110 if (bsa->sa_flags & SA_RESETHAND) 111 lsa->lsa_flags |= LINUX_SA_ONESHOT; 112 if (bsa->sa_flags & SA_NODEFER) 113 lsa->lsa_flags |= LINUX_SA_NOMASK; 114 } 115 116 int 117 linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa, 118 l_sigaction_t *linux_osa) 119 { 120 struct sigaction act, oact, *nsa, *osa; 121 int error, sig; 122 123 if (!LINUX_SIG_VALID(linux_sig)) 124 return (EINVAL); 125 126 osa = (linux_osa != NULL) ? &oact : NULL; 127 if (linux_nsa != NULL) { 128 nsa = &act; 129 linux_to_bsd_sigaction(linux_nsa, nsa); 130 } else 131 nsa = NULL; 132 sig = linux_to_bsd_signal(linux_sig); 133 134 error = kern_sigaction(td, sig, nsa, osa, 0); 135 if (error) 136 return (error); 137 138 if (linux_osa != NULL) 139 bsd_to_linux_sigaction(osa, linux_osa); 140 141 return (0); 142 } 143 144 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 145 int 146 linux_signal(struct thread *td, struct linux_signal_args *args) 147 { 148 l_sigaction_t nsa, osa; 149 int error; 150 151 #ifdef DEBUG 152 if (ldebug(signal)) 153 printf(ARGS(signal, "%d, %p"), 154 args->sig, (void *)(uintptr_t)args->handler); 155 #endif 156 157 nsa.lsa_handler = args->handler; 158 nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; 159 LINUX_SIGEMPTYSET(nsa.lsa_mask); 160 161 error = linux_do_sigaction(td, args->sig, &nsa, &osa); 162 td->td_retval[0] = (int)(intptr_t)osa.lsa_handler; 163 164 return (error); 165 } 166 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 167 168 int 169 linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args) 170 { 171 l_sigaction_t nsa, osa; 172 int error; 173 174 #ifdef DEBUG 175 if (ldebug(rt_sigaction)) 176 printf(ARGS(rt_sigaction, "%ld, %p, %p, %ld"), 177 (long)args->sig, (void *)args->act, 178 (void *)args->oact, (long)args->sigsetsize); 179 #endif 180 181 if (args->sigsetsize != sizeof(l_sigset_t)) 182 return (EINVAL); 183 184 if (args->act != NULL) { 185 error = copyin(args->act, &nsa, sizeof(l_sigaction_t)); 186 if (error) 187 return (error); 188 } 189 190 error = linux_do_sigaction(td, args->sig, 191 args->act ? &nsa : NULL, 192 args->oact ? &osa : NULL); 193 194 if (args->oact != NULL && !error) { 195 error = copyout(&osa, args->oact, sizeof(l_sigaction_t)); 196 } 197 198 return (error); 199 } 200 201 static int 202 linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new, 203 l_sigset_t *old) 204 { 205 sigset_t omask, nmask; 206 sigset_t *nmaskp; 207 int error; 208 209 td->td_retval[0] = 0; 210 211 switch (how) { 212 case LINUX_SIG_BLOCK: 213 how = SIG_BLOCK; 214 break; 215 case LINUX_SIG_UNBLOCK: 216 how = SIG_UNBLOCK; 217 break; 218 case LINUX_SIG_SETMASK: 219 how = SIG_SETMASK; 220 break; 221 default: 222 return (EINVAL); 223 } 224 if (new != NULL) { 225 linux_to_bsd_sigset(new, &nmask); 226 nmaskp = &nmask; 227 } else 228 nmaskp = NULL; 229 error = kern_sigprocmask(td, how, nmaskp, &omask, 0); 230 if (error == 0 && old != NULL) 231 bsd_to_linux_sigset(&omask, old); 232 233 return (error); 234 } 235 236 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 237 int 238 linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args) 239 { 240 l_osigset_t mask; 241 l_sigset_t set, oset; 242 int error; 243 244 #ifdef DEBUG 245 if (ldebug(sigprocmask)) 246 printf(ARGS(sigprocmask, "%d, *, *"), args->how); 247 #endif 248 249 if (args->mask != NULL) { 250 error = copyin(args->mask, &mask, sizeof(l_osigset_t)); 251 if (error) 252 return (error); 253 LINUX_SIGEMPTYSET(set); 254 set.__mask = mask; 255 } 256 257 error = linux_do_sigprocmask(td, args->how, 258 args->mask ? &set : NULL, 259 args->omask ? &oset : NULL); 260 261 if (args->omask != NULL && !error) { 262 mask = oset.__mask; 263 error = copyout(&mask, args->omask, sizeof(l_osigset_t)); 264 } 265 266 return (error); 267 } 268 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 269 270 int 271 linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args) 272 { 273 l_sigset_t set, oset; 274 int error; 275 276 #ifdef DEBUG 277 if (ldebug(rt_sigprocmask)) 278 printf(ARGS(rt_sigprocmask, "%d, %p, %p, %ld"), 279 args->how, (void *)args->mask, 280 (void *)args->omask, (long)args->sigsetsize); 281 #endif 282 283 if (args->sigsetsize != sizeof(l_sigset_t)) 284 return EINVAL; 285 286 if (args->mask != NULL) { 287 error = copyin(args->mask, &set, sizeof(l_sigset_t)); 288 if (error) 289 return (error); 290 } 291 292 error = linux_do_sigprocmask(td, args->how, 293 args->mask ? &set : NULL, 294 args->omask ? &oset : NULL); 295 296 if (args->omask != NULL && !error) { 297 error = copyout(&oset, args->omask, sizeof(l_sigset_t)); 298 } 299 300 return (error); 301 } 302 303 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 304 int 305 linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args) 306 { 307 struct proc *p = td->td_proc; 308 l_sigset_t mask; 309 310 #ifdef DEBUG 311 if (ldebug(sgetmask)) 312 printf(ARGS(sgetmask, "")); 313 #endif 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 #ifdef DEBUG 330 if (ldebug(ssetmask)) 331 printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask); 332 #endif 333 334 PROC_LOCK(p); 335 bsd_to_linux_sigset(&td->td_sigmask, &lset); 336 td->td_retval[0] = lset.__mask; 337 LINUX_SIGEMPTYSET(lset); 338 lset.__mask = args->mask; 339 linux_to_bsd_sigset(&lset, &bset); 340 td->td_sigmask = bset; 341 SIG_CANTMASK(td->td_sigmask); 342 signotify(td); 343 PROC_UNLOCK(p); 344 return (0); 345 } 346 347 int 348 linux_sigpending(struct thread *td, struct linux_sigpending_args *args) 349 { 350 struct proc *p = td->td_proc; 351 sigset_t bset; 352 l_sigset_t lset; 353 l_osigset_t mask; 354 355 #ifdef DEBUG 356 if (ldebug(sigpending)) 357 printf(ARGS(sigpending, "*")); 358 #endif 359 360 PROC_LOCK(p); 361 bset = p->p_siglist; 362 SIGSETOR(bset, td->td_siglist); 363 SIGSETAND(bset, td->td_sigmask); 364 PROC_UNLOCK(p); 365 bsd_to_linux_sigset(&bset, &lset); 366 mask = lset.__mask; 367 return (copyout(&mask, args->mask, sizeof(mask))); 368 } 369 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 370 371 /* 372 * MPSAFE 373 */ 374 int 375 linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args) 376 { 377 struct proc *p = td->td_proc; 378 sigset_t bset; 379 l_sigset_t lset; 380 381 if (args->sigsetsize > sizeof(lset)) 382 return EINVAL; 383 /* NOT REACHED */ 384 385 #ifdef DEBUG 386 if (ldebug(rt_sigpending)) 387 printf(ARGS(rt_sigpending, "*")); 388 #endif 389 390 PROC_LOCK(p); 391 bset = p->p_siglist; 392 SIGSETOR(bset, td->td_siglist); 393 SIGSETAND(bset, td->td_sigmask); 394 PROC_UNLOCK(p); 395 bsd_to_linux_sigset(&bset, &lset); 396 return (copyout(&lset, args->set, args->sigsetsize)); 397 } 398 399 /* 400 * MPSAFE 401 */ 402 int 403 linux_rt_sigtimedwait(struct thread *td, 404 struct linux_rt_sigtimedwait_args *args) 405 { 406 int error, sig; 407 l_timeval ltv; 408 struct timeval tv; 409 struct timespec ts, *tsa; 410 l_sigset_t lset; 411 sigset_t bset; 412 l_siginfo_t linfo; 413 ksiginfo_t info; 414 415 #ifdef DEBUG 416 if (ldebug(rt_sigtimedwait)) 417 printf(ARGS(rt_sigtimedwait, "*")); 418 #endif 419 if (args->sigsetsize != sizeof(l_sigset_t)) 420 return (EINVAL); 421 422 if ((error = copyin(args->mask, &lset, sizeof(lset)))) 423 return (error); 424 linux_to_bsd_sigset(&lset, &bset); 425 426 tsa = NULL; 427 if (args->timeout) { 428 if ((error = copyin(args->timeout, <v, sizeof(ltv)))) 429 return (error); 430 #ifdef DEBUG 431 if (ldebug(rt_sigtimedwait)) 432 printf(LMSG("linux_rt_sigtimedwait: " 433 "incoming timeout (%jd/%jd)\n"), 434 (intmax_t)ltv.tv_sec, (intmax_t)ltv.tv_usec); 435 #endif 436 tv.tv_sec = (long)ltv.tv_sec; 437 tv.tv_usec = (suseconds_t)ltv.tv_usec; 438 if (itimerfix(&tv)) { 439 /* 440 * The timeout was invalid. Convert it to something 441 * valid that will act as it does under Linux. 442 */ 443 tv.tv_sec += tv.tv_usec / 1000000; 444 tv.tv_usec %= 1000000; 445 if (tv.tv_usec < 0) { 446 tv.tv_sec -= 1; 447 tv.tv_usec += 1000000; 448 } 449 if (tv.tv_sec < 0) 450 timevalclear(&tv); 451 #ifdef DEBUG 452 if (ldebug(rt_sigtimedwait)) 453 printf(LMSG("linux_rt_sigtimedwait: " 454 "converted timeout (%jd/%ld)\n"), 455 (intmax_t)tv.tv_sec, tv.tv_usec); 456 #endif 457 } 458 TIMEVAL_TO_TIMESPEC(&tv, &ts); 459 tsa = &ts; 460 } 461 error = kern_sigtimedwait(td, bset, &info, tsa); 462 #ifdef DEBUG 463 if (ldebug(rt_sigtimedwait)) 464 printf(LMSG("linux_rt_sigtimedwait: " 465 "sigtimedwait returning (%d)\n"), error); 466 #endif 467 if (error) 468 return (error); 469 470 sig = bsd_to_linux_signal(info.ksi_signo); 471 472 if (args->ptr) { 473 memset(&linfo, 0, sizeof(linfo)); 474 ksiginfo_to_lsiginfo(&info, &linfo, sig); 475 error = copyout(&linfo, args->ptr, sizeof(linfo)); 476 } 477 if (error == 0) 478 td->td_retval[0] = sig; 479 480 return (error); 481 } 482 483 int 484 linux_kill(struct thread *td, struct linux_kill_args *args) 485 { 486 struct kill_args /* { 487 int pid; 488 int signum; 489 } */ tmp; 490 491 #ifdef DEBUG 492 if (ldebug(kill)) 493 printf(ARGS(kill, "%d, %d"), args->pid, args->signum); 494 #endif 495 496 /* 497 * Allow signal 0 as a means to check for privileges 498 */ 499 if (!LINUX_SIG_VALID(args->signum) && args->signum != 0) 500 return (EINVAL); 501 502 if (args->signum > 0) 503 tmp.signum = linux_to_bsd_signal(args->signum); 504 else 505 tmp.signum = 0; 506 507 tmp.pid = args->pid; 508 return (sys_kill(td, &tmp)); 509 } 510 511 static int 512 linux_do_tkill(struct thread *td, struct thread *tdt, ksiginfo_t *ksi) 513 { 514 struct proc *p; 515 int error; 516 517 p = tdt->td_proc; 518 AUDIT_ARG_SIGNUM(ksi->ksi_signo); 519 AUDIT_ARG_PID(p->p_pid); 520 AUDIT_ARG_PROCESS(p); 521 522 error = p_cansignal(td, p, ksi->ksi_signo); 523 if (error != 0 || ksi->ksi_signo == 0) 524 goto out; 525 526 tdksignal(tdt, ksi->ksi_signo, ksi); 527 528 out: 529 PROC_UNLOCK(p); 530 return (error); 531 } 532 533 int 534 linux_tgkill(struct thread *td, struct linux_tgkill_args *args) 535 { 536 struct thread *tdt; 537 ksiginfo_t ksi; 538 int sig; 539 540 #ifdef DEBUG 541 if (ldebug(tgkill)) 542 printf(ARGS(tgkill, "%d, %d, %d"), 543 args->tgid, args->pid, args->sig); 544 #endif 545 546 if (args->pid <= 0 || args->tgid <=0) 547 return (EINVAL); 548 549 /* 550 * Allow signal 0 as a means to check for privileges 551 */ 552 if (!LINUX_SIG_VALID(args->sig) && args->sig != 0) 553 return (EINVAL); 554 555 if (args->sig > 0) 556 sig = linux_to_bsd_signal(args->sig); 557 else 558 sig = 0; 559 560 tdt = linux_tdfind(td, args->pid, args->tgid); 561 if (tdt == NULL) 562 return (ESRCH); 563 564 ksiginfo_init(&ksi); 565 ksi.ksi_signo = sig; 566 ksi.ksi_code = SI_LWP; 567 ksi.ksi_errno = 0; 568 ksi.ksi_pid = td->td_proc->p_pid; 569 ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 570 return (linux_do_tkill(td, tdt, &ksi)); 571 } 572 573 /* 574 * Deprecated since 2.5.75. Replaced by tgkill(). 575 */ 576 int 577 linux_tkill(struct thread *td, struct linux_tkill_args *args) 578 { 579 struct thread *tdt; 580 ksiginfo_t ksi; 581 int sig; 582 583 #ifdef DEBUG 584 if (ldebug(tkill)) 585 printf(ARGS(tkill, "%i, %i"), args->tid, args->sig); 586 #endif 587 if (args->tid <= 0) 588 return (EINVAL); 589 590 if (!LINUX_SIG_VALID(args->sig)) 591 return (EINVAL); 592 593 sig = linux_to_bsd_signal(args->sig); 594 595 tdt = linux_tdfind(td, args->tid, -1); 596 if (tdt == NULL) 597 return (ESRCH); 598 599 ksiginfo_init(&ksi); 600 ksi.ksi_signo = sig; 601 ksi.ksi_code = SI_LWP; 602 ksi.ksi_errno = 0; 603 ksi.ksi_pid = td->td_proc->p_pid; 604 ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 605 return (linux_do_tkill(td, tdt, &ksi)); 606 } 607 608 void 609 ksiginfo_to_lsiginfo(const ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig) 610 { 611 612 siginfo_to_lsiginfo(&ksi->ksi_info, lsi, sig); 613 } 614 615 static void 616 sicode_to_lsicode(int si_code, int *lsi_code) 617 { 618 619 switch (si_code) { 620 case SI_USER: 621 *lsi_code = LINUX_SI_USER; 622 break; 623 case SI_KERNEL: 624 *lsi_code = LINUX_SI_KERNEL; 625 break; 626 case SI_QUEUE: 627 *lsi_code = LINUX_SI_QUEUE; 628 break; 629 case SI_TIMER: 630 *lsi_code = LINUX_SI_TIMER; 631 break; 632 case SI_MESGQ: 633 *lsi_code = LINUX_SI_MESGQ; 634 break; 635 case SI_ASYNCIO: 636 *lsi_code = LINUX_SI_ASYNCIO; 637 break; 638 case SI_LWP: 639 *lsi_code = LINUX_SI_TKILL; 640 break; 641 default: 642 *lsi_code = si_code; 643 break; 644 } 645 } 646 647 void 648 siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig) 649 { 650 651 /* sig alredy converted */ 652 lsi->lsi_signo = sig; 653 sicode_to_lsicode(si->si_code, &lsi->lsi_code); 654 655 switch (si->si_code) { 656 case SI_LWP: 657 lsi->lsi_pid = si->si_pid; 658 lsi->lsi_uid = si->si_uid; 659 break; 660 661 case SI_TIMER: 662 lsi->lsi_int = si->si_value.sival_int; 663 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 664 lsi->lsi_tid = si->si_timerid; 665 break; 666 667 case SI_QUEUE: 668 lsi->lsi_pid = si->si_pid; 669 lsi->lsi_uid = si->si_uid; 670 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 671 break; 672 673 case SI_ASYNCIO: 674 lsi->lsi_int = si->si_value.sival_int; 675 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 676 break; 677 678 default: 679 switch (sig) { 680 case LINUX_SIGPOLL: 681 /* XXX si_fd? */ 682 lsi->lsi_band = si->si_band; 683 break; 684 685 case LINUX_SIGCHLD: 686 lsi->lsi_errno = 0; 687 lsi->lsi_pid = si->si_pid; 688 lsi->lsi_uid = si->si_uid; 689 690 if (si->si_code == CLD_STOPPED) 691 lsi->lsi_status = bsd_to_linux_signal(si->si_status); 692 else if (si->si_code == CLD_CONTINUED) 693 lsi->lsi_status = bsd_to_linux_signal(SIGCONT); 694 else 695 lsi->lsi_status = si->si_status; 696 break; 697 698 case LINUX_SIGBUS: 699 case LINUX_SIGILL: 700 case LINUX_SIGFPE: 701 case LINUX_SIGSEGV: 702 lsi->lsi_addr = PTROUT(si->si_addr); 703 break; 704 705 default: 706 lsi->lsi_pid = si->si_pid; 707 lsi->lsi_uid = si->si_uid; 708 if (sig >= LINUX_SIGRTMIN) { 709 lsi->lsi_int = si->si_value.sival_int; 710 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 711 } 712 break; 713 } 714 break; 715 } 716 } 717 718 void 719 lsiginfo_to_ksiginfo(const l_siginfo_t *lsi, ksiginfo_t *ksi, int sig) 720 { 721 722 ksi->ksi_signo = sig; 723 ksi->ksi_code = lsi->lsi_code; /* XXX. Convert. */ 724 ksi->ksi_pid = lsi->lsi_pid; 725 ksi->ksi_uid = lsi->lsi_uid; 726 ksi->ksi_status = lsi->lsi_status; 727 ksi->ksi_addr = PTRIN(lsi->lsi_addr); 728 ksi->ksi_info.si_value.sival_int = lsi->lsi_int; 729 } 730 731 int 732 linux_rt_sigqueueinfo(struct thread *td, struct linux_rt_sigqueueinfo_args *args) 733 { 734 l_siginfo_t linfo; 735 struct proc *p; 736 ksiginfo_t ksi; 737 int error; 738 int sig; 739 740 if (!LINUX_SIG_VALID(args->sig)) 741 return (EINVAL); 742 743 error = copyin(args->info, &linfo, sizeof(linfo)); 744 if (error != 0) 745 return (error); 746 747 if (linfo.lsi_code >= 0) 748 return (EPERM); 749 750 sig = linux_to_bsd_signal(args->sig); 751 752 error = ESRCH; 753 if ((p = pfind_any(args->pid)) != NULL) { 754 error = p_cansignal(td, p, sig); 755 if (error != 0) { 756 PROC_UNLOCK(p); 757 return (error); 758 } 759 760 ksiginfo_init(&ksi); 761 lsiginfo_to_ksiginfo(&linfo, &ksi, sig); 762 error = tdsendsignal(p, NULL, sig, &ksi); 763 PROC_UNLOCK(p); 764 } 765 766 return (error); 767 } 768 769 int 770 linux_rt_tgsigqueueinfo(struct thread *td, struct linux_rt_tgsigqueueinfo_args *args) 771 { 772 l_siginfo_t linfo; 773 struct thread *tds; 774 ksiginfo_t ksi; 775 int error; 776 int sig; 777 778 if (!LINUX_SIG_VALID(args->sig)) 779 return (EINVAL); 780 781 error = copyin(args->uinfo, &linfo, sizeof(linfo)); 782 if (error != 0) 783 return (error); 784 785 if (linfo.lsi_code >= 0) 786 return (EPERM); 787 788 tds = linux_tdfind(td, args->tid, args->tgid); 789 if (tds == NULL) 790 return (ESRCH); 791 792 sig = linux_to_bsd_signal(args->sig); 793 ksiginfo_init(&ksi); 794 lsiginfo_to_ksiginfo(&linfo, &ksi, sig); 795 return (linux_do_tkill(td, tds, &ksi)); 796 } 797