linux_signal.c revision 293498
1139749Simp/*- 2102445Sjhb * Copyright (c) 1994-1995 S��ren Schmidt 3102445Sjhb * All rights reserved. 4102445Sjhb * 5102445Sjhb * Redistribution and use in source and binary forms, with or without 6102445Sjhb * modification, are permitted provided that the following conditions 7102445Sjhb * are met: 8102445Sjhb * 1. Redistributions of source code must retain the above copyright 9102445Sjhb * notice, this list of conditions and the following disclaimer 10102445Sjhb * in this position and unchanged. 11102445Sjhb * 2. Redistributions in binary form must reproduce the above copyright 12102445Sjhb * notice, this list of conditions and the following disclaimer in the 13102445Sjhb * documentation and/or other materials provided with the distribution. 14102445Sjhb * 3. The name of the author may not be used to endorse or promote products 15102445Sjhb * derived from this software without specific prior written permission 16102445Sjhb * 17102445Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18102445Sjhb * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19102445Sjhb * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20102445Sjhb * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21102445Sjhb * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22102445Sjhb * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23102445Sjhb * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24102445Sjhb * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25102445Sjhb * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26102445Sjhb * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27102445Sjhb */ 28102445Sjhb 29119418Sobrien#include <sys/cdefs.h> 30119418Sobrien__FBSDID("$FreeBSD: stable/10/sys/compat/linux/linux_signal.c 293498 2016-01-09 15:21:45Z dchagin $"); 31119418Sobrien 32259512Skib#include <sys/param.h> 33259512Skib#include <sys/systm.h> 34102445Sjhb#include <sys/lock.h> 35102445Sjhb#include <sys/mutex.h> 36102445Sjhb#include <sys/sx.h> 37102445Sjhb#include <sys/proc.h> 38102445Sjhb#include <sys/signalvar.h> 39102445Sjhb#include <sys/syscallsubr.h> 40102445Sjhb#include <sys/sysproto.h> 41193530Sjkim 42193530Sjkim#include <security/audit/audit.h> 43193530Sjkim 44102445Sjhb#include "opt_compat.h" 45102445Sjhb 46102445Sjhb#ifdef COMPAT_LINUX32 47102445Sjhb#include <machine/../linux32/linux.h> 48102445Sjhb#include <machine/../linux32/linux32_proto.h> 49102445Sjhb#else 50102445Sjhb#include <machine/../linux/linux.h> 51102445Sjhb#include <machine/../linux/linux_proto.h> 52102445Sjhb#endif 53102445Sjhb#include <compat/linux/linux_signal.h> 54129829Snjl#include <compat/linux/linux_util.h> 55102445Sjhb#include <compat/linux/linux_emul.h> 56102445Sjhb#include <compat/linux/linux_misc.h> 57102445Sjhb 58102445Sjhbstatic int linux_do_tkill(struct thread *td, struct thread *tdt, 59129829Snjl ksiginfo_t *ksi); 60129829Snjlstatic void sicode_to_lsicode(int si_code, int *lsi_code); 61131341Snjl 62102445Sjhb 63102445Sjhbvoid 64133619Snjllinux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss) 65133619Snjl{ 66138200Snjl int b, l; 67138200Snjl 68138200Snjl SIGEMPTYSET(*bss); 69138200Snjl bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); 70138200Snjl bss->__bits[1] = lss->__bits[1]; 71138200Snjl for (l = 1; l <= LINUX_SIGTBLSZ; l++) { 72130978Sjhb if (LINUX_SIGISMEMBER(*lss, l)) { 73130978Sjhb b = linux_to_bsd_signal[_SIG_IDX(l)]; 74130978Sjhb if (b) 75102445Sjhb SIGADDSET(*bss, b); 76102445Sjhb } 77129829Snjl } 78131341Snjl} 79131341Snjl 80130978Sjhbvoid 81130978Sjhbbsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss) 82102445Sjhb{ 83129829Snjl int b, l; 84130978Sjhb 85259512Skib LINUX_SIGEMPTYSET(*lss); 86102445Sjhb lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1); 87102445Sjhb lss->__bits[1] = bss->__bits[1]; 88102445Sjhb for (b = 1; b <= LINUX_SIGTBLSZ; b++) { 89102445Sjhb if (SIGISMEMBER(*bss, b)) { 90102445Sjhb l = bsd_to_linux_signal[_SIG_IDX(b)]; 91102445Sjhb if (l) 92102445Sjhb LINUX_SIGADDSET(*lss, l); 93102445Sjhb } 94131341Snjl } 95127680Stakawata} 96259512Skib 97102445Sjhbstatic void 98102445Sjhblinux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa) 99128016Sjhb{ 100102445Sjhb 101246128Ssbz linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask); 102102445Sjhb bsa->sa_handler = PTRIN(lsa->lsa_handler); 103102445Sjhb bsa->sa_flags = 0; 104154600Sjhb if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) 105102445Sjhb bsa->sa_flags |= SA_NOCLDSTOP; 106232403Sjhb if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) 107232403Sjhb bsa->sa_flags |= SA_NOCLDWAIT; 108102445Sjhb if (lsa->lsa_flags & LINUX_SA_SIGINFO) 109128071Snjl bsa->sa_flags |= SA_SIGINFO; 110128071Snjl if (lsa->lsa_flags & LINUX_SA_ONSTACK) 111102445Sjhb bsa->sa_flags |= SA_ONSTACK; 112102445Sjhb if (lsa->lsa_flags & LINUX_SA_RESTART) 113102445Sjhb bsa->sa_flags |= SA_RESTART; 114102445Sjhb if (lsa->lsa_flags & LINUX_SA_ONESHOT) 115102445Sjhb bsa->sa_flags |= SA_RESETHAND; 116102445Sjhb if (lsa->lsa_flags & LINUX_SA_NOMASK) 117102445Sjhb bsa->sa_flags |= SA_NODEFER; 118131341Snjl} 119102445Sjhb 120127681Snjlstatic void 121102445Sjhbbsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa) 122127681Snjl{ 123131341Snjl 124131341Snjl bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask); 125131341Snjl#ifdef COMPAT_LINUX32 126102445Sjhb lsa->lsa_handler = (uintptr_t)bsa->sa_handler; 127127681Snjl#else 128102445Sjhb lsa->lsa_handler = bsa->sa_handler; 129102445Sjhb#endif 130127680Stakawata lsa->lsa_restorer = 0; /* unsupported */ 131131341Snjl lsa->lsa_flags = 0; 132131341Snjl if (bsa->sa_flags & SA_NOCLDSTOP) 133131341Snjl lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; 134131341Snjl if (bsa->sa_flags & SA_NOCLDWAIT) 135131341Snjl lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; 136131341Snjl if (bsa->sa_flags & SA_SIGINFO) 137131341Snjl lsa->lsa_flags |= LINUX_SA_SIGINFO; 138131341Snjl if (bsa->sa_flags & SA_ONSTACK) 139131341Snjl lsa->lsa_flags |= LINUX_SA_ONSTACK; 140131341Snjl if (bsa->sa_flags & SA_RESTART) 141131341Snjl lsa->lsa_flags |= LINUX_SA_RESTART; 142131341Snjl if (bsa->sa_flags & SA_RESETHAND) 143131341Snjl lsa->lsa_flags |= LINUX_SA_ONESHOT; 144131341Snjl if (bsa->sa_flags & SA_NODEFER) 145131341Snjl lsa->lsa_flags |= LINUX_SA_NOMASK; 146131341Snjl} 147131341Snjl 148127680Stakawataint 149127680Stakawatalinux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa, 150127680Stakawata l_sigaction_t *linux_osa) 151127680Stakawata{ 152127681Snjl struct sigaction act, oact, *nsa, *osa; 153127680Stakawata int error, sig; 154127680Stakawata 155127681Snjl if (!LINUX_SIG_VALID(linux_sig)) 156132136Stakawata return (EINVAL); 157127680Stakawata 158127680Stakawata osa = (linux_osa != NULL) ? &oact : NULL; 159127680Stakawata if (linux_nsa != NULL) { 160127680Stakawata nsa = &act; 161127680Stakawata linux_to_bsd_sigaction(linux_nsa, nsa); 162102445Sjhb } else 163102445Sjhb nsa = NULL; 164102445Sjhb 165102445Sjhb if (linux_sig <= LINUX_SIGTBLSZ) 166102445Sjhb sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)]; 167102445Sjhb else 168128247Snjl sig = linux_sig; 169128016Sjhb 170138200Snjl error = kern_sigaction(td, sig, nsa, osa, 0); 171102445Sjhb if (error) 172133619Snjl return (error); 173138200Snjl 174128016Sjhb if (linux_osa != NULL) 175128016Sjhb bsd_to_linux_sigaction(osa, linux_osa); 176128016Sjhb 177128016Sjhb return (0); 178128016Sjhb} 179128016Sjhb 180128016Sjhb 181128016Sjhbint 182128016Sjhblinux_signal(struct thread *td, struct linux_signal_args *args) 183128016Sjhb{ 184128016Sjhb l_sigaction_t nsa, osa; 185133619Snjl int error; 186128016Sjhb 187214110Sjkim#ifdef DEBUG 188128016Sjhb if (ldebug(signal)) 189128016Sjhb printf(ARGS(signal, "%d, %p"), 190133619Snjl args->sig, (void *)(uintptr_t)args->handler); 191128016Sjhb#endif 192130210Snjl 193138200Snjl nsa.lsa_handler = args->handler; 194214072Sjkim nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; 195214072Sjkim LINUX_SIGEMPTYSET(nsa.lsa_mask); 196214072Sjkim 197214072Sjkim error = linux_do_sigaction(td, args->sig, &nsa, &osa); 198214072Sjkim td->td_retval[0] = (int)(intptr_t)osa.lsa_handler; 199130208Snjl 200214072Sjkim return (error); 201138200Snjl} 202214068Sjkim 203133619Snjlint 204133619Snjllinux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args) 205133619Snjl{ 206133619Snjl l_sigaction_t nsa, osa; 207133619Snjl int error; 208102445Sjhb 209102445Sjhb#ifdef DEBUG 210130978Sjhb if (ldebug(rt_sigaction)) 211130978Sjhb printf(ARGS(rt_sigaction, "%ld, %p, %p, %ld"), 212130978Sjhb (long)args->sig, (void *)args->act, 213130978Sjhb (void *)args->oact, (long)args->sigsetsize); 214130978Sjhb#endif 215130978Sjhb 216130978Sjhb if (args->sigsetsize != sizeof(l_sigset_t)) 217223207Sjhb return (EINVAL); 218223207Sjhb 219223207Sjhb if (args->act != NULL) { 220223207Sjhb error = copyin(args->act, &nsa, sizeof(l_sigaction_t)); 221223207Sjhb if (error) 222130978Sjhb return (error); 223130978Sjhb } 224130978Sjhb 225130978Sjhb error = linux_do_sigaction(td, args->sig, 226130978Sjhb args->act ? &nsa : NULL, 227130978Sjhb args->oact ? &osa : NULL); 228130978Sjhb 229223207Sjhb if (args->oact != NULL && !error) { 230130978Sjhb error = copyout(&osa, args->oact, sizeof(l_sigaction_t)); 231130978Sjhb } 232130978Sjhb 233130978Sjhb return (error); 234130978Sjhb} 235131009Snjl 236130978Sjhbstatic int 237130978Sjhblinux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new, 238130978Sjhb l_sigset_t *old) 239130978Sjhb{ 240130978Sjhb sigset_t omask, nmask; 241102445Sjhb sigset_t *nmaskp; 242102445Sjhb int error; 243102445Sjhb 244102445Sjhb td->td_retval[0] = 0; 245102445Sjhb 246102445Sjhb switch (how) { 247102445Sjhb case LINUX_SIG_BLOCK: 248102445Sjhb how = SIG_BLOCK; 249102445Sjhb break; 250102445Sjhb case LINUX_SIG_UNBLOCK: 251102445Sjhb how = SIG_UNBLOCK; 252126560Snjl break; 253129829Snjl case LINUX_SIG_SETMASK: 254135574Sjhb how = SIG_SETMASK; 255135574Sjhb break; 256102445Sjhb default: 257129829Snjl return (EINVAL); 258102445Sjhb } 259102445Sjhb if (new != NULL) { 260102445Sjhb linux_to_bsd_sigset(new, &nmask); 261102445Sjhb nmaskp = &nmask; 262102445Sjhb } else 263130978Sjhb nmaskp = NULL; 264131009Snjl error = kern_sigprocmask(td, how, nmaskp, &omask, 0); 265102445Sjhb if (error == 0 && old != NULL) 266102445Sjhb bsd_to_linux_sigset(&omask, old); 267102445Sjhb 268129829Snjl return (error); 269102445Sjhb} 270102445Sjhb 271102445Sjhbint 272102445Sjhblinux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args) 273102445Sjhb{ 274102445Sjhb l_osigset_t mask; 275102445Sjhb l_sigset_t set, oset; 276102445Sjhb int error; 277129829Snjl 278102445Sjhb#ifdef DEBUG 279102445Sjhb if (ldebug(sigprocmask)) 280102445Sjhb printf(ARGS(sigprocmask, "%d, *, *"), args->how); 281102445Sjhb#endif 282102445Sjhb 283102445Sjhb if (args->mask != NULL) { 284232403Sjhb error = copyin(args->mask, &mask, sizeof(l_osigset_t)); 285102445Sjhb if (error) 286232403Sjhb return (error); 287232403Sjhb LINUX_SIGEMPTYSET(set); 288232403Sjhb set.__bits[0] = mask; 289232403Sjhb } 290102445Sjhb 291102445Sjhb error = linux_do_sigprocmask(td, args->how, 292158457Sjhb args->mask ? &set : NULL, 293158457Sjhb args->omask ? &oset : NULL); 294172394Smarius 295102445Sjhb if (args->omask != NULL && !error) { 296172394Smarius mask = oset.__bits[0]; 297102445Sjhb error = copyout(&mask, args->omask, sizeof(l_osigset_t)); 298102445Sjhb } 299102445Sjhb 300102445Sjhb return (error); 301102445Sjhb} 302102445Sjhb 303102445Sjhbint 304102445Sjhblinux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args) 305102445Sjhb{ 306102445Sjhb l_sigset_t set, oset; 307102445Sjhb int error; 308102445Sjhb 309172394Smarius#ifdef DEBUG 310129829Snjl if (ldebug(rt_sigprocmask)) 311199337Sjkim printf(ARGS(rt_sigprocmask, "%d, %p, %p, %ld"), 312102445Sjhb args->how, (void *)args->mask, 313102445Sjhb (void *)args->omask, (long)args->sigsetsize); 314102445Sjhb#endif 315259512Skib 316259512Skib if (args->sigsetsize != sizeof(l_sigset_t)) 317259512Skib return EINVAL; 318259512Skib 319259512Skib if (args->mask != NULL) { 320259512Skib error = copyin(args->mask, &set, sizeof(l_sigset_t)); 321259512Skib if (error) 322259512Skib return (error); 323259512Skib } 324259512Skib 325259512Skib error = linux_do_sigprocmask(td, args->how, 326259512Skib args->mask ? &set : NULL, 327259512Skib args->omask ? &oset : NULL); 328259512Skib 329259512Skib if (args->omask != NULL && !error) { 330259512Skib error = copyout(&oset, args->omask, sizeof(l_sigset_t)); 331259512Skib } 332259512Skib 333259512Skib return (error); 334259512Skib} 335259512Skib 336259512Skibint 337259512Skiblinux_sgetmask(struct thread *td, struct linux_sgetmask_args *args) 338259512Skib{ 339259512Skib struct proc *p = td->td_proc; 340 l_sigset_t mask; 341 342#ifdef DEBUG 343 if (ldebug(sgetmask)) 344 printf(ARGS(sgetmask, "")); 345#endif 346 347 PROC_LOCK(p); 348 bsd_to_linux_sigset(&td->td_sigmask, &mask); 349 PROC_UNLOCK(p); 350 td->td_retval[0] = mask.__bits[0]; 351 return (0); 352} 353 354int 355linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args) 356{ 357 struct proc *p = td->td_proc; 358 l_sigset_t lset; 359 sigset_t bset; 360 361#ifdef DEBUG 362 if (ldebug(ssetmask)) 363 printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask); 364#endif 365 366 PROC_LOCK(p); 367 bsd_to_linux_sigset(&td->td_sigmask, &lset); 368 td->td_retval[0] = lset.__bits[0]; 369 LINUX_SIGEMPTYSET(lset); 370 lset.__bits[0] = args->mask; 371 linux_to_bsd_sigset(&lset, &bset); 372 td->td_sigmask = bset; 373 SIG_CANTMASK(td->td_sigmask); 374 signotify(td); 375 PROC_UNLOCK(p); 376 return (0); 377} 378 379/* 380 * MPSAFE 381 */ 382int 383linux_sigpending(struct thread *td, struct linux_sigpending_args *args) 384{ 385 struct proc *p = td->td_proc; 386 sigset_t bset; 387 l_sigset_t lset; 388 l_osigset_t mask; 389 390#ifdef DEBUG 391 if (ldebug(sigpending)) 392 printf(ARGS(sigpending, "*")); 393#endif 394 395 PROC_LOCK(p); 396 bset = p->p_siglist; 397 SIGSETOR(bset, td->td_siglist); 398 SIGSETAND(bset, td->td_sigmask); 399 PROC_UNLOCK(p); 400 bsd_to_linux_sigset(&bset, &lset); 401 mask = lset.__bits[0]; 402 return (copyout(&mask, args->mask, sizeof(mask))); 403} 404 405/* 406 * MPSAFE 407 */ 408int 409linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args) 410{ 411 struct proc *p = td->td_proc; 412 sigset_t bset; 413 l_sigset_t lset; 414 415 if (args->sigsetsize > sizeof(lset)) 416 return EINVAL; 417 /* NOT REACHED */ 418 419#ifdef DEBUG 420 if (ldebug(rt_sigpending)) 421 printf(ARGS(rt_sigpending, "*")); 422#endif 423 424 PROC_LOCK(p); 425 bset = p->p_siglist; 426 SIGSETOR(bset, td->td_siglist); 427 SIGSETAND(bset, td->td_sigmask); 428 PROC_UNLOCK(p); 429 bsd_to_linux_sigset(&bset, &lset); 430 return (copyout(&lset, args->set, args->sigsetsize)); 431} 432 433/* 434 * MPSAFE 435 */ 436int 437linux_rt_sigtimedwait(struct thread *td, 438 struct linux_rt_sigtimedwait_args *args) 439{ 440 int error, sig; 441 l_timeval ltv; 442 struct timeval tv; 443 struct timespec ts, *tsa; 444 l_sigset_t lset; 445 sigset_t bset; 446 l_siginfo_t linfo; 447 ksiginfo_t info; 448 449#ifdef DEBUG 450 if (ldebug(rt_sigtimedwait)) 451 printf(ARGS(rt_sigtimedwait, "*")); 452#endif 453 if (args->sigsetsize != sizeof(l_sigset_t)) 454 return (EINVAL); 455 456 if ((error = copyin(args->mask, &lset, sizeof(lset)))) 457 return (error); 458 linux_to_bsd_sigset(&lset, &bset); 459 460 tsa = NULL; 461 if (args->timeout) { 462 if ((error = copyin(args->timeout, <v, sizeof(ltv)))) 463 return (error); 464#ifdef DEBUG 465 if (ldebug(rt_sigtimedwait)) 466 printf(LMSG("linux_rt_sigtimedwait: " 467 "incoming timeout (%d/%d)\n"), 468 ltv.tv_sec, ltv.tv_usec); 469#endif 470 tv.tv_sec = (long)ltv.tv_sec; 471 tv.tv_usec = (suseconds_t)ltv.tv_usec; 472 if (itimerfix(&tv)) { 473 /* 474 * The timeout was invalid. Convert it to something 475 * valid that will act as it does under Linux. 476 */ 477 tv.tv_sec += tv.tv_usec / 1000000; 478 tv.tv_usec %= 1000000; 479 if (tv.tv_usec < 0) { 480 tv.tv_sec -= 1; 481 tv.tv_usec += 1000000; 482 } 483 if (tv.tv_sec < 0) 484 timevalclear(&tv); 485#ifdef DEBUG 486 if (ldebug(rt_sigtimedwait)) 487 printf(LMSG("linux_rt_sigtimedwait: " 488 "converted timeout (%jd/%ld)\n"), 489 (intmax_t)tv.tv_sec, tv.tv_usec); 490#endif 491 } 492 TIMEVAL_TO_TIMESPEC(&tv, &ts); 493 tsa = &ts; 494 } 495 error = kern_sigtimedwait(td, bset, &info, tsa); 496#ifdef DEBUG 497 if (ldebug(rt_sigtimedwait)) 498 printf(LMSG("linux_rt_sigtimedwait: " 499 "sigtimedwait returning (%d)\n"), error); 500#endif 501 if (error) 502 return (error); 503 504 sig = BSD_TO_LINUX_SIGNAL(info.ksi_signo); 505 506 if (args->ptr) { 507 memset(&linfo, 0, sizeof(linfo)); 508 ksiginfo_to_lsiginfo(&info, &linfo, sig); 509 error = copyout(&linfo, args->ptr, sizeof(linfo)); 510 } 511 if (error == 0) 512 td->td_retval[0] = sig; 513 514 return (error); 515} 516 517int 518linux_kill(struct thread *td, struct linux_kill_args *args) 519{ 520 struct kill_args /* { 521 int pid; 522 int signum; 523 } */ tmp; 524 525#ifdef DEBUG 526 if (ldebug(kill)) 527 printf(ARGS(kill, "%d, %d"), args->pid, args->signum); 528#endif 529 530 /* 531 * Allow signal 0 as a means to check for privileges 532 */ 533 if (!LINUX_SIG_VALID(args->signum) && args->signum != 0) 534 return (EINVAL); 535 536 if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ) 537 tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)]; 538 else 539 tmp.signum = args->signum; 540 541 tmp.pid = args->pid; 542 return (sys_kill(td, &tmp)); 543} 544 545static int 546linux_do_tkill(struct thread *td, struct thread *tdt, ksiginfo_t *ksi) 547{ 548 struct proc *p; 549 int error; 550 551 p = tdt->td_proc; 552 AUDIT_ARG_SIGNUM(ksi->ksi_signo); 553 AUDIT_ARG_PID(p->p_pid); 554 AUDIT_ARG_PROCESS(p); 555 556 error = p_cansignal(td, p, ksi->ksi_signo); 557 if (error != 0 || ksi->ksi_signo == 0) 558 goto out; 559 560 tdksignal(tdt, ksi->ksi_signo, ksi); 561 562out: 563 PROC_UNLOCK(p); 564 return (error); 565} 566 567int 568linux_tgkill(struct thread *td, struct linux_tgkill_args *args) 569{ 570 struct thread *tdt; 571 ksiginfo_t ksi; 572 int sig; 573 574#ifdef DEBUG 575 if (ldebug(tgkill)) 576 printf(ARGS(tgkill, "%d, %d, %d"), 577 args->tgid, args->pid, args->sig); 578#endif 579 580 if (args->pid <= 0 || args->tgid <=0) 581 return (EINVAL); 582 583 /* 584 * Allow signal 0 as a means to check for privileges 585 */ 586 if (!LINUX_SIG_VALID(args->sig) && args->sig != 0) 587 return (EINVAL); 588 589 if (args->sig > 0 && args->sig <= LINUX_SIGTBLSZ) 590 sig = linux_to_bsd_signal[_SIG_IDX(args->sig)]; 591 else 592 sig = args->sig; 593 594 tdt = linux_tdfind(td, args->pid, args->tgid); 595 if (tdt == NULL) 596 return (ESRCH); 597 598 ksiginfo_init(&ksi); 599 ksi.ksi_signo = sig; 600 ksi.ksi_code = SI_LWP; 601 ksi.ksi_errno = 0; 602 ksi.ksi_pid = td->td_proc->p_pid; 603 ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 604 return (linux_do_tkill(td, tdt, &ksi)); 605} 606 607/* 608 * Deprecated since 2.5.75. Replaced by tgkill(). 609 */ 610int 611linux_tkill(struct thread *td, struct linux_tkill_args *args) 612{ 613 struct thread *tdt; 614 ksiginfo_t ksi; 615 int sig; 616 617#ifdef DEBUG 618 if (ldebug(tkill)) 619 printf(ARGS(tkill, "%i, %i"), args->tid, args->sig); 620#endif 621 if (args->tid <= 0) 622 return (EINVAL); 623 624 if (!LINUX_SIG_VALID(args->sig)) 625 return (EINVAL); 626 627 if (args->sig > 0 && args->sig <= LINUX_SIGTBLSZ) 628 sig = linux_to_bsd_signal[_SIG_IDX(args->sig)]; 629 else 630 sig = args->sig; 631 632 tdt = linux_tdfind(td, args->tid, -1); 633 if (tdt == NULL) 634 return (ESRCH); 635 636 ksiginfo_init(&ksi); 637 ksi.ksi_signo = sig; 638 ksi.ksi_code = SI_LWP; 639 ksi.ksi_errno = 0; 640 ksi.ksi_pid = td->td_proc->p_pid; 641 ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 642 return (linux_do_tkill(td, tdt, &ksi)); 643} 644 645void 646ksiginfo_to_lsiginfo(const ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig) 647{ 648 649 siginfo_to_lsiginfo(&ksi->ksi_info, lsi, sig); 650} 651 652static void 653sicode_to_lsicode(int si_code, int *lsi_code) 654{ 655 656 switch (si_code) { 657 case SI_USER: 658 *lsi_code = LINUX_SI_USER; 659 break; 660 case SI_KERNEL: 661 *lsi_code = LINUX_SI_KERNEL; 662 break; 663 case SI_QUEUE: 664 *lsi_code = LINUX_SI_QUEUE; 665 break; 666 case SI_TIMER: 667 *lsi_code = LINUX_SI_TIMER; 668 break; 669 case SI_MESGQ: 670 *lsi_code = LINUX_SI_MESGQ; 671 break; 672 case SI_ASYNCIO: 673 *lsi_code = LINUX_SI_ASYNCIO; 674 break; 675 case SI_LWP: 676 *lsi_code = LINUX_SI_TKILL; 677 break; 678 default: 679 *lsi_code = si_code; 680 break; 681 } 682} 683 684void 685siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig) 686{ 687 688 /* sig alredy converted */ 689 lsi->lsi_signo = sig; 690 sicode_to_lsicode(si->si_code, &lsi->lsi_code); 691 692 switch (si->si_code) { 693 case SI_LWP: 694 lsi->lsi_pid = si->si_pid; 695 lsi->lsi_uid = si->si_uid; 696 break; 697 698 case SI_TIMER: 699 lsi->lsi_int = si->si_value.sival_int; 700 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 701 lsi->lsi_tid = si->si_timerid; 702 break; 703 704 case SI_QUEUE: 705 lsi->lsi_pid = si->si_pid; 706 lsi->lsi_uid = si->si_uid; 707 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 708 break; 709 710 case SI_ASYNCIO: 711 lsi->lsi_int = si->si_value.sival_int; 712 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 713 break; 714 715 default: 716 switch (sig) { 717 case LINUX_SIGPOLL: 718 /* XXX si_fd? */ 719 lsi->lsi_band = si->si_band; 720 break; 721 722 case LINUX_SIGCHLD: 723 lsi->lsi_errno = 0; 724 lsi->lsi_pid = si->si_pid; 725 lsi->lsi_uid = si->si_uid; 726 727 if (si->si_code == CLD_STOPPED) 728 lsi->lsi_status = BSD_TO_LINUX_SIGNAL(si->si_status); 729 else if (si->si_code == CLD_CONTINUED) 730 lsi->lsi_status = BSD_TO_LINUX_SIGNAL(SIGCONT); 731 else 732 lsi->lsi_status = si->si_status; 733 break; 734 735 case LINUX_SIGBUS: 736 case LINUX_SIGILL: 737 case LINUX_SIGFPE: 738 case LINUX_SIGSEGV: 739 lsi->lsi_addr = PTROUT(si->si_addr); 740 break; 741 742 default: 743 lsi->lsi_pid = si->si_pid; 744 lsi->lsi_uid = si->si_uid; 745 if (sig >= LINUX_SIGRTMIN) { 746 lsi->lsi_int = si->si_value.sival_int; 747 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 748 } 749 break; 750 } 751 break; 752 } 753} 754