1c21dee17SSøren Schmidt /*- 20ba1b365SEd Maste * SPDX-License-Identifier: BSD-2-Clause 37f2d13d6SPedro F. Giffuni * 49a14aa01SUlrich Spörlein * Copyright (c) 1994-1995 Søren Schmidt 5c21dee17SSøren Schmidt * All rights reserved. 6c21dee17SSøren Schmidt * 7c21dee17SSøren Schmidt * Redistribution and use in source and binary forms, with or without 8c21dee17SSøren Schmidt * modification, are permitted provided that the following conditions 9c21dee17SSøren Schmidt * are met: 10c21dee17SSøren Schmidt * 1. Redistributions of source code must retain the above copyright 110ba1b365SEd Maste * notice, this list of conditions and the following disclaimer. 12c21dee17SSøren Schmidt * 2. Redistributions in binary form must reproduce the above copyright 13c21dee17SSøren Schmidt * notice, this list of conditions and the following disclaimer in the 14c21dee17SSøren Schmidt * documentation and/or other materials provided with the distribution. 15c21dee17SSøren Schmidt * 160ba1b365SEd Maste * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 170ba1b365SEd Maste * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 180ba1b365SEd Maste * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 190ba1b365SEd Maste * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 200ba1b365SEd Maste * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 210ba1b365SEd Maste * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 220ba1b365SEd Maste * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 230ba1b365SEd Maste * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 240ba1b365SEd Maste * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 250ba1b365SEd Maste * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 260ba1b365SEd Maste * SUCH DAMAGE. 27c21dee17SSøren Schmidt */ 28c21dee17SSøren Schmidt 2916dbc7f2SDavid E. O'Brien #include <sys/cdefs.h> 301e8d246eSNate Lawson __FBSDID("$FreeBSD$"); 3116dbc7f2SDavid E. O'Brien 32c21dee17SSøren Schmidt #include <sys/param.h> 33c21dee17SSøren Schmidt #include <sys/systm.h> 34fb919e4dSMark Murray #include <sys/lock.h> 35fb919e4dSMark Murray #include <sys/mutex.h> 3629ddc19bSAlexander Leidinger #include <sys/sx.h> 37c21dee17SSøren Schmidt #include <sys/proc.h> 38c21dee17SSøren Schmidt #include <sys/signalvar.h> 39206a5d3aSIan Dowse #include <sys/syscallsubr.h> 40fb919e4dSMark Murray #include <sys/sysproto.h> 41c21dee17SSøren Schmidt 42aa8b2011SKonstantin Belousov #include <security/audit/audit.h> 43aa8b2011SKonstantin Belousov 44aefce619SRuslan Ermilov #include "opt_compat.h" 45aefce619SRuslan Ermilov 461997c537SDavid E. O'Brien #ifdef COMPAT_LINUX32 474af27623STim J. Robbins #include <machine/../linux32/linux.h> 484af27623STim J. Robbins #include <machine/../linux32/linux32_proto.h> 491997c537SDavid E. O'Brien #else 501997c537SDavid E. O'Brien #include <machine/../linux/linux.h> 511997c537SDavid E. O'Brien #include <machine/../linux/linux_proto.h> 524af27623STim J. Robbins #endif 539c1045ffSDmitry Chagin #include <compat/linux/linux_mib.h> 54ba9ef45bSMarcel Moolenaar #include <compat/linux/linux_signal.h> 550f8dab45SDmitry Chagin #include <compat/linux/linux_timer.h> 56ba9ef45bSMarcel Moolenaar #include <compat/linux/linux_util.h> 579b44bfc5SAlexander Leidinger #include <compat/linux/linux_emul.h> 5881338031SDmitry Chagin #include <compat/linux/linux_misc.h> 5981338031SDmitry Chagin 6081338031SDmitry Chagin static int linux_do_tkill(struct thread *td, struct thread *tdt, 6181338031SDmitry Chagin ksiginfo_t *ksi); 62fe4ed1e7SDmitry Chagin static void sicode_to_lsicode(int si_code, int *lsi_code); 63db4a1f33SDmitry Chagin static int linux_common_rt_sigtimedwait(struct thread *, 64db4a1f33SDmitry Chagin l_sigset_t *, struct timespec *, l_siginfo_t *, 65db4a1f33SDmitry Chagin l_size_t); 66fe4ed1e7SDmitry Chagin 67a1ebcbfbSPeter Wemm static void 685002a60fSMarcel Moolenaar linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa) 69d66a5066SPeter Wemm { 70d5629eb2SEdward Tomasz Napierala unsigned long flags; 71956d3333SMarcel Moolenaar 72956d3333SMarcel Moolenaar linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask); 734af27623STim J. Robbins bsa->sa_handler = PTRIN(lsa->lsa_handler); 74d66a5066SPeter Wemm bsa->sa_flags = 0; 75d5629eb2SEdward Tomasz Napierala 76d5629eb2SEdward Tomasz Napierala flags = lsa->lsa_flags; 77d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) { 78d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_NOCLDSTOP; 79d66a5066SPeter Wemm bsa->sa_flags |= SA_NOCLDSTOP; 80d5629eb2SEdward Tomasz Napierala } 81d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) { 82d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_NOCLDWAIT; 8306ebbe77SMarcel Moolenaar bsa->sa_flags |= SA_NOCLDWAIT; 84d5629eb2SEdward Tomasz Napierala } 85d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_SIGINFO) { 86d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_SIGINFO; 8706ebbe77SMarcel Moolenaar bsa->sa_flags |= SA_SIGINFO; 88d5629eb2SEdward Tomasz Napierala #ifdef notyet 89d5629eb2SEdward Tomasz Napierala /* 90d5629eb2SEdward Tomasz Napierala * XXX: We seem to be missing code to convert 91d5629eb2SEdward Tomasz Napierala * some of the fields in ucontext_t. 92d5629eb2SEdward Tomasz Napierala */ 93d5629eb2SEdward Tomasz Napierala linux_msg(curthread, 94d5629eb2SEdward Tomasz Napierala "partially unsupported sigaction flag SA_SIGINFO"); 95d5629eb2SEdward Tomasz Napierala #endif 96d5629eb2SEdward Tomasz Napierala } 97d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_RESTORER) { 98d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_RESTORER; 99*3eaf271dSEdward Tomasz Napierala /* 100*3eaf271dSEdward Tomasz Napierala * We ignore the lsa_restorer and always use our own signal 101*3eaf271dSEdward Tomasz Napierala * trampoline instead. It looks like SA_RESTORER is obsolete 102*3eaf271dSEdward Tomasz Napierala * in Linux too - it doesn't seem to be used at all on arm64. 103*3eaf271dSEdward Tomasz Napierala * In any case: see Linux sigreturn(2). 104*3eaf271dSEdward Tomasz Napierala */ 105d5629eb2SEdward Tomasz Napierala } 106d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_ONSTACK) { 107d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_ONSTACK; 108d66a5066SPeter Wemm bsa->sa_flags |= SA_ONSTACK; 109d5629eb2SEdward Tomasz Napierala } 110d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_RESTART) { 111d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_RESTART; 112d66a5066SPeter Wemm bsa->sa_flags |= SA_RESTART; 113d5629eb2SEdward Tomasz Napierala } 1149bc42c18SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_INTERRUPT) { 1159bc42c18SEdward Tomasz Napierala flags &= ~LINUX_SA_INTERRUPT; 1169bc42c18SEdward Tomasz Napierala /* Documented to be a "historical no-op". */ 1179bc42c18SEdward Tomasz Napierala } 118d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_ONESHOT) { 119d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_ONESHOT; 120d66a5066SPeter Wemm bsa->sa_flags |= SA_RESETHAND; 121d5629eb2SEdward Tomasz Napierala } 122d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_NOMASK) { 123d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_NOMASK; 124d66a5066SPeter Wemm bsa->sa_flags |= SA_NODEFER; 125d66a5066SPeter Wemm } 126d66a5066SPeter Wemm 127d5629eb2SEdward Tomasz Napierala if (flags != 0) 128d5629eb2SEdward Tomasz Napierala linux_msg(curthread, "unsupported sigaction flag %#lx", flags); 129d5629eb2SEdward Tomasz Napierala } 130d5629eb2SEdward Tomasz Napierala 131a1ebcbfbSPeter Wemm static void 1325002a60fSMarcel Moolenaar bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa) 133d66a5066SPeter Wemm { 134956d3333SMarcel Moolenaar 135956d3333SMarcel Moolenaar bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask); 1361997c537SDavid E. O'Brien #ifdef COMPAT_LINUX32 1374af27623STim J. Robbins lsa->lsa_handler = (uintptr_t)bsa->sa_handler; 1384af27623STim J. Robbins #else 1398f437f44SMartin Cracauer lsa->lsa_handler = bsa->sa_handler; 1404af27623STim J. Robbins #endif 1414af27623STim J. Robbins lsa->lsa_restorer = 0; /* unsupported */ 1428f437f44SMartin Cracauer lsa->lsa_flags = 0; 143d66a5066SPeter Wemm if (bsa->sa_flags & SA_NOCLDSTOP) 1448f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; 14506ebbe77SMarcel Moolenaar if (bsa->sa_flags & SA_NOCLDWAIT) 14606ebbe77SMarcel Moolenaar lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; 14706ebbe77SMarcel Moolenaar if (bsa->sa_flags & SA_SIGINFO) 14806ebbe77SMarcel Moolenaar lsa->lsa_flags |= LINUX_SA_SIGINFO; 149d66a5066SPeter Wemm if (bsa->sa_flags & SA_ONSTACK) 1508f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_ONSTACK; 151d66a5066SPeter Wemm if (bsa->sa_flags & SA_RESTART) 1528f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_RESTART; 153d66a5066SPeter Wemm if (bsa->sa_flags & SA_RESETHAND) 1548f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_ONESHOT; 155d66a5066SPeter Wemm if (bsa->sa_flags & SA_NODEFER) 1568f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_NOMASK; 157d66a5066SPeter Wemm } 158c21dee17SSøren Schmidt 159ba9ef45bSMarcel Moolenaar int 160b40ce416SJulian Elischer linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa, 1615002a60fSMarcel Moolenaar l_sigaction_t *linux_osa) 16206ebbe77SMarcel Moolenaar { 163206a5d3aSIan Dowse struct sigaction act, oact, *nsa, *osa; 164206a5d3aSIan Dowse int error, sig; 16506ebbe77SMarcel Moolenaar 166687c23beSAlexander Leidinger if (!LINUX_SIG_VALID(linux_sig)) 167956d3333SMarcel Moolenaar return (EINVAL); 16806ebbe77SMarcel Moolenaar 169206a5d3aSIan Dowse osa = (linux_osa != NULL) ? &oact : NULL; 170956d3333SMarcel Moolenaar if (linux_nsa != NULL) { 171206a5d3aSIan Dowse nsa = &act; 172ec99e322SMarcel Moolenaar linux_to_bsd_sigaction(linux_nsa, nsa); 173206a5d3aSIan Dowse } else 17406ebbe77SMarcel Moolenaar nsa = NULL; 1754ab7403bSDmitry Chagin sig = linux_to_bsd_signal(linux_sig); 176956d3333SMarcel Moolenaar 177206a5d3aSIan Dowse error = kern_sigaction(td, sig, nsa, osa, 0); 17806ebbe77SMarcel Moolenaar if (error) 179956d3333SMarcel Moolenaar return (error); 18006ebbe77SMarcel Moolenaar 181ec99e322SMarcel Moolenaar if (linux_osa != NULL) 182ec99e322SMarcel Moolenaar bsd_to_linux_sigaction(osa, linux_osa); 18306ebbe77SMarcel Moolenaar 184956d3333SMarcel Moolenaar return (0); 18506ebbe77SMarcel Moolenaar } 18606ebbe77SMarcel Moolenaar 1877f8f1d7fSDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 188c21dee17SSøren Schmidt int 189b40ce416SJulian Elischer linux_signal(struct thread *td, struct linux_signal_args *args) 190d66a5066SPeter Wemm { 1915002a60fSMarcel Moolenaar l_sigaction_t nsa, osa; 192d66a5066SPeter Wemm int error; 193d66a5066SPeter Wemm 19406ebbe77SMarcel Moolenaar nsa.lsa_handler = args->handler; 19506ebbe77SMarcel Moolenaar nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; 196956d3333SMarcel Moolenaar LINUX_SIGEMPTYSET(nsa.lsa_mask); 197d66a5066SPeter Wemm 198b40ce416SJulian Elischer error = linux_do_sigaction(td, args->sig, &nsa, &osa); 1994af27623STim J. Robbins td->td_retval[0] = (int)(intptr_t)osa.lsa_handler; 200d66a5066SPeter Wemm 201956d3333SMarcel Moolenaar return (error); 202d66a5066SPeter Wemm } 2037f8f1d7fSDmitry Chagin #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 204d66a5066SPeter Wemm 205c21dee17SSøren Schmidt int 206b40ce416SJulian Elischer linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args) 207c21dee17SSøren Schmidt { 2085002a60fSMarcel Moolenaar l_sigaction_t nsa, osa; 20906ebbe77SMarcel Moolenaar int error; 210c21dee17SSøren Schmidt 2115002a60fSMarcel Moolenaar if (args->sigsetsize != sizeof(l_sigset_t)) 212956d3333SMarcel Moolenaar return (EINVAL); 21306ebbe77SMarcel Moolenaar 214956d3333SMarcel Moolenaar if (args->act != NULL) { 2155002a60fSMarcel Moolenaar error = copyin(args->act, &nsa, sizeof(l_sigaction_t)); 21606ebbe77SMarcel Moolenaar if (error) 217956d3333SMarcel Moolenaar return (error); 21806ebbe77SMarcel Moolenaar } 21906ebbe77SMarcel Moolenaar 220b40ce416SJulian Elischer error = linux_do_sigaction(td, args->sig, 22106ebbe77SMarcel Moolenaar args->act ? &nsa : NULL, 22206ebbe77SMarcel Moolenaar args->oact ? &osa : NULL); 22306ebbe77SMarcel Moolenaar 224956d3333SMarcel Moolenaar if (args->oact != NULL && !error) { 2255002a60fSMarcel Moolenaar error = copyout(&osa, args->oact, sizeof(l_sigaction_t)); 22606ebbe77SMarcel Moolenaar } 22706ebbe77SMarcel Moolenaar 228956d3333SMarcel Moolenaar return (error); 22906ebbe77SMarcel Moolenaar } 23006ebbe77SMarcel Moolenaar 23106ebbe77SMarcel Moolenaar static int 232b40ce416SJulian Elischer linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new, 2335002a60fSMarcel Moolenaar l_sigset_t *old) 23406ebbe77SMarcel Moolenaar { 235fe8cdcaeSJohn Baldwin sigset_t omask, nmask; 236fe8cdcaeSJohn Baldwin sigset_t *nmaskp; 237216af822SJohn Baldwin int error; 23806ebbe77SMarcel Moolenaar 239b40ce416SJulian Elischer td->td_retval[0] = 0; 240d66a5066SPeter Wemm 24119dde5cdSJohn Baldwin switch (how) { 24219dde5cdSJohn Baldwin case LINUX_SIG_BLOCK: 24319dde5cdSJohn Baldwin how = SIG_BLOCK; 24419dde5cdSJohn Baldwin break; 24519dde5cdSJohn Baldwin case LINUX_SIG_UNBLOCK: 24619dde5cdSJohn Baldwin how = SIG_UNBLOCK; 24719dde5cdSJohn Baldwin break; 24819dde5cdSJohn Baldwin case LINUX_SIG_SETMASK: 24919dde5cdSJohn Baldwin how = SIG_SETMASK; 25019dde5cdSJohn Baldwin break; 25119dde5cdSJohn Baldwin default: 25219dde5cdSJohn Baldwin return (EINVAL); 25319dde5cdSJohn Baldwin } 25406ebbe77SMarcel Moolenaar if (new != NULL) { 255fe8cdcaeSJohn Baldwin linux_to_bsd_sigset(new, &nmask); 256fe8cdcaeSJohn Baldwin nmaskp = &nmask; 257fe8cdcaeSJohn Baldwin } else 258fe8cdcaeSJohn Baldwin nmaskp = NULL; 25919dde5cdSJohn Baldwin error = kern_sigprocmask(td, how, nmaskp, &omask, 0); 2602f7ed219SJohn Baldwin if (error == 0 && old != NULL) 261fe8cdcaeSJohn Baldwin bsd_to_linux_sigset(&omask, old); 26206ebbe77SMarcel Moolenaar 263956d3333SMarcel Moolenaar return (error); 26406ebbe77SMarcel Moolenaar } 26506ebbe77SMarcel Moolenaar 2667f8f1d7fSDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 26706ebbe77SMarcel Moolenaar int 268b40ce416SJulian Elischer linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args) 26906ebbe77SMarcel Moolenaar { 2705002a60fSMarcel Moolenaar l_osigset_t mask; 2715002a60fSMarcel Moolenaar l_sigset_t set, oset; 27206ebbe77SMarcel Moolenaar int error; 27306ebbe77SMarcel Moolenaar 27406ebbe77SMarcel Moolenaar if (args->mask != NULL) { 2755002a60fSMarcel Moolenaar error = copyin(args->mask, &mask, sizeof(l_osigset_t)); 27606ebbe77SMarcel Moolenaar if (error) 277956d3333SMarcel Moolenaar return (error); 278956d3333SMarcel Moolenaar LINUX_SIGEMPTYSET(set); 2794ab7403bSDmitry Chagin set.__mask = mask; 28006ebbe77SMarcel Moolenaar } 28106ebbe77SMarcel Moolenaar 282b40ce416SJulian Elischer error = linux_do_sigprocmask(td, args->how, 283956d3333SMarcel Moolenaar args->mask ? &set : NULL, 284956d3333SMarcel Moolenaar args->omask ? &oset : NULL); 28506ebbe77SMarcel Moolenaar 286956d3333SMarcel Moolenaar if (args->omask != NULL && !error) { 2874ab7403bSDmitry Chagin mask = oset.__mask; 2885002a60fSMarcel Moolenaar error = copyout(&mask, args->omask, sizeof(l_osigset_t)); 28906ebbe77SMarcel Moolenaar } 29006ebbe77SMarcel Moolenaar 291956d3333SMarcel Moolenaar return (error); 29206ebbe77SMarcel Moolenaar } 2937f8f1d7fSDmitry Chagin #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 29406ebbe77SMarcel Moolenaar 29506ebbe77SMarcel Moolenaar int 296b40ce416SJulian Elischer linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args) 29706ebbe77SMarcel Moolenaar { 2985002a60fSMarcel Moolenaar l_sigset_t set, oset; 29906ebbe77SMarcel Moolenaar int error; 30006ebbe77SMarcel Moolenaar 3015002a60fSMarcel Moolenaar if (args->sigsetsize != sizeof(l_sigset_t)) 302340f4a8dSEd Maste return (EINVAL); 30306ebbe77SMarcel Moolenaar 30406ebbe77SMarcel Moolenaar if (args->mask != NULL) { 3055002a60fSMarcel Moolenaar error = copyin(args->mask, &set, sizeof(l_sigset_t)); 30606ebbe77SMarcel Moolenaar if (error) 307956d3333SMarcel Moolenaar return (error); 30806ebbe77SMarcel Moolenaar } 30906ebbe77SMarcel Moolenaar 310b40ce416SJulian Elischer error = linux_do_sigprocmask(td, args->how, 311956d3333SMarcel Moolenaar args->mask ? &set : NULL, 312956d3333SMarcel Moolenaar args->omask ? &oset : NULL); 31306ebbe77SMarcel Moolenaar 314956d3333SMarcel Moolenaar if (args->omask != NULL && !error) { 3155002a60fSMarcel Moolenaar error = copyout(&oset, args->omask, sizeof(l_sigset_t)); 31606ebbe77SMarcel Moolenaar } 31706ebbe77SMarcel Moolenaar 318956d3333SMarcel Moolenaar return (error); 319c21dee17SSøren Schmidt } 320c21dee17SSøren Schmidt 3217f8f1d7fSDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 322c21dee17SSøren Schmidt int 323b40ce416SJulian Elischer linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args) 324c21dee17SSøren Schmidt { 325b40ce416SJulian Elischer struct proc *p = td->td_proc; 3265002a60fSMarcel Moolenaar l_sigset_t mask; 327956d3333SMarcel Moolenaar 328216af822SJohn Baldwin PROC_LOCK(p); 3294093529dSJeff Roberson bsd_to_linux_sigset(&td->td_sigmask, &mask); 330216af822SJohn Baldwin PROC_UNLOCK(p); 3314ab7403bSDmitry Chagin td->td_retval[0] = mask.__mask; 332956d3333SMarcel Moolenaar return (0); 333c21dee17SSøren Schmidt } 334c21dee17SSøren Schmidt 335c21dee17SSøren Schmidt int 336b40ce416SJulian Elischer linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args) 337c21dee17SSøren Schmidt { 338b40ce416SJulian Elischer struct proc *p = td->td_proc; 3395002a60fSMarcel Moolenaar l_sigset_t lset; 340956d3333SMarcel Moolenaar sigset_t bset; 341c21dee17SSøren Schmidt 342216af822SJohn Baldwin PROC_LOCK(p); 3434093529dSJeff Roberson bsd_to_linux_sigset(&td->td_sigmask, &lset); 3444ab7403bSDmitry Chagin td->td_retval[0] = lset.__mask; 345956d3333SMarcel Moolenaar LINUX_SIGEMPTYSET(lset); 3464ab7403bSDmitry Chagin lset.__mask = args->mask; 347956d3333SMarcel Moolenaar linux_to_bsd_sigset(&lset, &bset); 3484093529dSJeff Roberson td->td_sigmask = bset; 3494093529dSJeff Roberson SIG_CANTMASK(td->td_sigmask); 3504093529dSJeff Roberson signotify(td); 351216af822SJohn Baldwin PROC_UNLOCK(p); 352956d3333SMarcel Moolenaar return (0); 353c21dee17SSøren Schmidt } 354c21dee17SSøren Schmidt 355c21dee17SSøren Schmidt int 356b40ce416SJulian Elischer linux_sigpending(struct thread *td, struct linux_sigpending_args *args) 357c21dee17SSøren Schmidt { 358b40ce416SJulian Elischer struct proc *p = td->td_proc; 359956d3333SMarcel Moolenaar sigset_t bset; 3605002a60fSMarcel Moolenaar l_sigset_t lset; 3615002a60fSMarcel Moolenaar l_osigset_t mask; 362c21dee17SSøren Schmidt 363216af822SJohn Baldwin PROC_LOCK(p); 3641d9c5696SJuli Mallett bset = p->p_siglist; 3654093529dSJeff Roberson SIGSETOR(bset, td->td_siglist); 3664093529dSJeff Roberson SIGSETAND(bset, td->td_sigmask); 367216af822SJohn Baldwin PROC_UNLOCK(p); 3689d8643ecSJohn Baldwin bsd_to_linux_sigset(&bset, &lset); 3694ab7403bSDmitry Chagin mask = lset.__mask; 370956d3333SMarcel Moolenaar return (copyout(&mask, args->mask, sizeof(mask))); 371c21dee17SSøren Schmidt } 3727f8f1d7fSDmitry Chagin #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 37317138b61SAlexander Leidinger 37417138b61SAlexander Leidinger /* 37517138b61SAlexander Leidinger * MPSAFE 37617138b61SAlexander Leidinger */ 37717138b61SAlexander Leidinger int 37817138b61SAlexander Leidinger linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args) 37917138b61SAlexander Leidinger { 38017138b61SAlexander Leidinger struct proc *p = td->td_proc; 38117138b61SAlexander Leidinger sigset_t bset; 38217138b61SAlexander Leidinger l_sigset_t lset; 38317138b61SAlexander Leidinger 38417138b61SAlexander Leidinger if (args->sigsetsize > sizeof(lset)) 385340f4a8dSEd Maste return (EINVAL); 38617138b61SAlexander Leidinger /* NOT REACHED */ 38717138b61SAlexander Leidinger 38817138b61SAlexander Leidinger PROC_LOCK(p); 38917138b61SAlexander Leidinger bset = p->p_siglist; 39017138b61SAlexander Leidinger SIGSETOR(bset, td->td_siglist); 39117138b61SAlexander Leidinger SIGSETAND(bset, td->td_sigmask); 39217138b61SAlexander Leidinger PROC_UNLOCK(p); 39317138b61SAlexander Leidinger bsd_to_linux_sigset(&bset, &lset); 39417138b61SAlexander Leidinger return (copyout(&lset, args->set, args->sigsetsize)); 39517138b61SAlexander Leidinger } 396c21dee17SSøren Schmidt 397c9447c75SAlexander Leidinger int 398c9447c75SAlexander Leidinger linux_rt_sigtimedwait(struct thread *td, 399c9447c75SAlexander Leidinger struct linux_rt_sigtimedwait_args *args) 400c9447c75SAlexander Leidinger { 401c9447c75SAlexander Leidinger struct timespec ts, *tsa; 4020f8dab45SDmitry Chagin struct l_timespec lts; 403db4a1f33SDmitry Chagin int error; 404c9447c75SAlexander Leidinger 405c9447c75SAlexander Leidinger if (args->timeout) { 4060f8dab45SDmitry Chagin if ((error = copyin(args->timeout, <s, sizeof(lts)))) 407c9447c75SAlexander Leidinger return (error); 4080f8dab45SDmitry Chagin error = linux_to_native_timespec(&ts, <s); 4090f8dab45SDmitry Chagin if (error != 0) 4100f8dab45SDmitry Chagin return (error); 411c9447c75SAlexander Leidinger tsa = &ts; 4120f8dab45SDmitry Chagin } else 4130f8dab45SDmitry Chagin tsa = NULL; 4140f8dab45SDmitry Chagin 415db4a1f33SDmitry Chagin return (linux_common_rt_sigtimedwait(td, args->mask, tsa, 416db4a1f33SDmitry Chagin args->ptr, args->sigsetsize)); 417db4a1f33SDmitry Chagin } 418db4a1f33SDmitry Chagin 419db4a1f33SDmitry Chagin static int 420db4a1f33SDmitry Chagin linux_common_rt_sigtimedwait(struct thread *td, l_sigset_t *mask, 421db4a1f33SDmitry Chagin struct timespec *tsa, l_siginfo_t *ptr, l_size_t sigsetsize) 422db4a1f33SDmitry Chagin { 423db4a1f33SDmitry Chagin int error, sig; 424db4a1f33SDmitry Chagin l_sigset_t lset; 425db4a1f33SDmitry Chagin sigset_t bset; 426db4a1f33SDmitry Chagin l_siginfo_t lsi; 427db4a1f33SDmitry Chagin ksiginfo_t ksi; 428db4a1f33SDmitry Chagin 429db4a1f33SDmitry Chagin if (sigsetsize != sizeof(l_sigset_t)) 430db4a1f33SDmitry Chagin return (EINVAL); 431db4a1f33SDmitry Chagin 432db4a1f33SDmitry Chagin if ((error = copyin(mask, &lset, sizeof(lset)))) 433db4a1f33SDmitry Chagin return (error); 434db4a1f33SDmitry Chagin linux_to_bsd_sigset(&lset, &bset); 435db4a1f33SDmitry Chagin 436db4a1f33SDmitry Chagin ksiginfo_init(&ksi); 437f4e80108SDmitry Chagin error = kern_sigtimedwait(td, bset, &ksi, tsa); 438c9447c75SAlexander Leidinger if (error) 439c9447c75SAlexander Leidinger return (error); 440c9447c75SAlexander Leidinger 441f4e80108SDmitry Chagin sig = bsd_to_linux_signal(ksi.ksi_signo); 442f3481dd9SDmitry Chagin 443db4a1f33SDmitry Chagin if (ptr) { 444f4e80108SDmitry Chagin memset(&lsi, 0, sizeof(lsi)); 445f4e80108SDmitry Chagin siginfo_to_lsiginfo(&ksi.ksi_info, &lsi, sig); 446db4a1f33SDmitry Chagin error = copyout(&lsi, ptr, sizeof(lsi)); 447c9447c75SAlexander Leidinger } 448f3481dd9SDmitry Chagin if (error == 0) 449f3481dd9SDmitry Chagin td->td_retval[0] = sig; 450c9447c75SAlexander Leidinger 451c9447c75SAlexander Leidinger return (error); 452c9447c75SAlexander Leidinger } 453c9447c75SAlexander Leidinger 454db4a1f33SDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 455db4a1f33SDmitry Chagin int 456db4a1f33SDmitry Chagin linux_rt_sigtimedwait_time64(struct thread *td, 457db4a1f33SDmitry Chagin struct linux_rt_sigtimedwait_time64_args *args) 458db4a1f33SDmitry Chagin { 459db4a1f33SDmitry Chagin struct timespec ts, *tsa; 460db4a1f33SDmitry Chagin struct l_timespec64 lts; 461db4a1f33SDmitry Chagin int error; 462db4a1f33SDmitry Chagin 463db4a1f33SDmitry Chagin if (args->timeout) { 464db4a1f33SDmitry Chagin if ((error = copyin(args->timeout, <s, sizeof(lts)))) 465db4a1f33SDmitry Chagin return (error); 466db4a1f33SDmitry Chagin error = linux_to_native_timespec64(&ts, <s); 467db4a1f33SDmitry Chagin if (error != 0) 468db4a1f33SDmitry Chagin return (error); 469db4a1f33SDmitry Chagin tsa = &ts; 470db4a1f33SDmitry Chagin } else 471db4a1f33SDmitry Chagin tsa = NULL; 472db4a1f33SDmitry Chagin 473db4a1f33SDmitry Chagin return (linux_common_rt_sigtimedwait(td, args->mask, tsa, 474db4a1f33SDmitry Chagin args->ptr, args->sigsetsize)); 475db4a1f33SDmitry Chagin } 476db4a1f33SDmitry Chagin #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 477db4a1f33SDmitry Chagin 478c21dee17SSøren Schmidt int 479b40ce416SJulian Elischer linux_kill(struct thread *td, struct linux_kill_args *args) 480c21dee17SSøren Schmidt { 48134ad5ac2SEdward Tomasz Napierala int l_signum; 482c21dee17SSøren Schmidt 483956d3333SMarcel Moolenaar /* 484956d3333SMarcel Moolenaar * Allow signal 0 as a means to check for privileges 485956d3333SMarcel Moolenaar */ 48664742216SAlexander Leidinger if (!LINUX_SIG_VALID(args->signum) && args->signum != 0) 4879a6a64d3SDmitry Chagin return (EINVAL); 488956d3333SMarcel Moolenaar 4894ab7403bSDmitry Chagin if (args->signum > 0) 49034ad5ac2SEdward Tomasz Napierala l_signum = linux_to_bsd_signal(args->signum); 491956d3333SMarcel Moolenaar else 49234ad5ac2SEdward Tomasz Napierala l_signum = 0; 493956d3333SMarcel Moolenaar 49434ad5ac2SEdward Tomasz Napierala return (kern_kill(td, args->pid, l_signum)); 495c21dee17SSøren Schmidt } 4969b44bfc5SAlexander Leidinger 497aa8b2011SKonstantin Belousov static int 49881338031SDmitry Chagin linux_do_tkill(struct thread *td, struct thread *tdt, ksiginfo_t *ksi) 499aa8b2011SKonstantin Belousov { 500aa8b2011SKonstantin Belousov struct proc *p; 501aa8b2011SKonstantin Belousov int error; 502aa8b2011SKonstantin Belousov 50381338031SDmitry Chagin p = tdt->td_proc; 50481338031SDmitry Chagin AUDIT_ARG_SIGNUM(ksi->ksi_signo); 50581338031SDmitry Chagin AUDIT_ARG_PID(p->p_pid); 50614961ba7SRobert Watson AUDIT_ARG_PROCESS(p); 50781338031SDmitry Chagin 50881338031SDmitry Chagin error = p_cansignal(td, p, ksi->ksi_signo); 50981338031SDmitry Chagin if (error != 0 || ksi->ksi_signo == 0) 510aa8b2011SKonstantin Belousov goto out; 511aa8b2011SKonstantin Belousov 51281338031SDmitry Chagin tdksignal(tdt, ksi->ksi_signo, ksi); 513aa8b2011SKonstantin Belousov 514aa8b2011SKonstantin Belousov out: 515aa8b2011SKonstantin Belousov PROC_UNLOCK(p); 516aa8b2011SKonstantin Belousov return (error); 517aa8b2011SKonstantin Belousov } 518aa8b2011SKonstantin Belousov 5199b44bfc5SAlexander Leidinger int 5209b44bfc5SAlexander Leidinger linux_tgkill(struct thread *td, struct linux_tgkill_args *args) 5219b44bfc5SAlexander Leidinger { 52281338031SDmitry Chagin struct thread *tdt; 52381338031SDmitry Chagin ksiginfo_t ksi; 52481338031SDmitry Chagin int sig; 5259b44bfc5SAlexander Leidinger 526aa8b2011SKonstantin Belousov if (args->pid <= 0 || args->tgid <=0) 527aa8b2011SKonstantin Belousov return (EINVAL); 5289b44bfc5SAlexander Leidinger 52981338031SDmitry Chagin /* 53081338031SDmitry Chagin * Allow signal 0 as a means to check for privileges 53181338031SDmitry Chagin */ 53281338031SDmitry Chagin if (!LINUX_SIG_VALID(args->sig) && args->sig != 0) 53381338031SDmitry Chagin return (EINVAL); 53481338031SDmitry Chagin 5354ab7403bSDmitry Chagin if (args->sig > 0) 5364ab7403bSDmitry Chagin sig = linux_to_bsd_signal(args->sig); 53781338031SDmitry Chagin else 5384ab7403bSDmitry Chagin sig = 0; 53981338031SDmitry Chagin 54081338031SDmitry Chagin tdt = linux_tdfind(td, args->pid, args->tgid); 54181338031SDmitry Chagin if (tdt == NULL) 54281338031SDmitry Chagin return (ESRCH); 54381338031SDmitry Chagin 54481338031SDmitry Chagin ksiginfo_init(&ksi); 54581338031SDmitry Chagin ksi.ksi_signo = sig; 546fe4ed1e7SDmitry Chagin ksi.ksi_code = SI_LWP; 54781338031SDmitry Chagin ksi.ksi_errno = 0; 54881338031SDmitry Chagin ksi.ksi_pid = td->td_proc->p_pid; 54981338031SDmitry Chagin ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 55081338031SDmitry Chagin return (linux_do_tkill(td, tdt, &ksi)); 5519b44bfc5SAlexander Leidinger } 5529b44bfc5SAlexander Leidinger 55381338031SDmitry Chagin /* 55481338031SDmitry Chagin * Deprecated since 2.5.75. Replaced by tgkill(). 55581338031SDmitry Chagin */ 5569b44bfc5SAlexander Leidinger int 5579b44bfc5SAlexander Leidinger linux_tkill(struct thread *td, struct linux_tkill_args *args) 5589b44bfc5SAlexander Leidinger { 55981338031SDmitry Chagin struct thread *tdt; 56081338031SDmitry Chagin ksiginfo_t ksi; 56181338031SDmitry Chagin int sig; 56281338031SDmitry Chagin 563aa8b2011SKonstantin Belousov if (args->tid <= 0) 564aa8b2011SKonstantin Belousov return (EINVAL); 5659b44bfc5SAlexander Leidinger 56681338031SDmitry Chagin if (!LINUX_SIG_VALID(args->sig)) 56781338031SDmitry Chagin return (EINVAL); 56881338031SDmitry Chagin 5694ab7403bSDmitry Chagin sig = linux_to_bsd_signal(args->sig); 57081338031SDmitry Chagin 57181338031SDmitry Chagin tdt = linux_tdfind(td, args->tid, -1); 57281338031SDmitry Chagin if (tdt == NULL) 57381338031SDmitry Chagin return (ESRCH); 57481338031SDmitry Chagin 57581338031SDmitry Chagin ksiginfo_init(&ksi); 57681338031SDmitry Chagin ksi.ksi_signo = sig; 577fe4ed1e7SDmitry Chagin ksi.ksi_code = SI_LWP; 57881338031SDmitry Chagin ksi.ksi_errno = 0; 57981338031SDmitry Chagin ksi.ksi_pid = td->td_proc->p_pid; 58081338031SDmitry Chagin ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 58181338031SDmitry Chagin return (linux_do_tkill(td, tdt, &ksi)); 582aa8b2011SKonstantin Belousov } 583aa8b2011SKonstantin Belousov 584fe4ed1e7SDmitry Chagin static void 585fe4ed1e7SDmitry Chagin sicode_to_lsicode(int si_code, int *lsi_code) 586fe4ed1e7SDmitry Chagin { 587fe4ed1e7SDmitry Chagin 588fe4ed1e7SDmitry Chagin switch (si_code) { 589fe4ed1e7SDmitry Chagin case SI_USER: 590fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_USER; 591fe4ed1e7SDmitry Chagin break; 592fe4ed1e7SDmitry Chagin case SI_KERNEL: 593fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_KERNEL; 594fe4ed1e7SDmitry Chagin break; 595fe4ed1e7SDmitry Chagin case SI_QUEUE: 596fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_QUEUE; 597fe4ed1e7SDmitry Chagin break; 598fe4ed1e7SDmitry Chagin case SI_TIMER: 599fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_TIMER; 600fe4ed1e7SDmitry Chagin break; 601fe4ed1e7SDmitry Chagin case SI_MESGQ: 602fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_MESGQ; 603fe4ed1e7SDmitry Chagin break; 604fe4ed1e7SDmitry Chagin case SI_ASYNCIO: 605fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_ASYNCIO; 606fe4ed1e7SDmitry Chagin break; 607fe4ed1e7SDmitry Chagin case SI_LWP: 608fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_TKILL; 609fe4ed1e7SDmitry Chagin break; 610fe4ed1e7SDmitry Chagin default: 611fe4ed1e7SDmitry Chagin *lsi_code = si_code; 612fe4ed1e7SDmitry Chagin break; 613fe4ed1e7SDmitry Chagin } 614fe4ed1e7SDmitry Chagin } 615fe4ed1e7SDmitry Chagin 616fe4ed1e7SDmitry Chagin void 617fe4ed1e7SDmitry Chagin siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig) 618fe4ed1e7SDmitry Chagin { 619fe4ed1e7SDmitry Chagin 620fe4ed1e7SDmitry Chagin /* sig alredy converted */ 621fe4ed1e7SDmitry Chagin lsi->lsi_signo = sig; 622fe4ed1e7SDmitry Chagin sicode_to_lsicode(si->si_code, &lsi->lsi_code); 623fe4ed1e7SDmitry Chagin 624fe4ed1e7SDmitry Chagin switch (si->si_code) { 625fe4ed1e7SDmitry Chagin case SI_LWP: 626fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 627fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 628fe4ed1e7SDmitry Chagin break; 629fe4ed1e7SDmitry Chagin 630fe4ed1e7SDmitry Chagin case SI_TIMER: 631fe4ed1e7SDmitry Chagin lsi->lsi_int = si->si_value.sival_int; 632fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 633fe4ed1e7SDmitry Chagin lsi->lsi_tid = si->si_timerid; 634fe4ed1e7SDmitry Chagin break; 635fe4ed1e7SDmitry Chagin 636fe4ed1e7SDmitry Chagin case SI_QUEUE: 637fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 638fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 639fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 640fe4ed1e7SDmitry Chagin break; 641fe4ed1e7SDmitry Chagin 642fe4ed1e7SDmitry Chagin case SI_ASYNCIO: 643fe4ed1e7SDmitry Chagin lsi->lsi_int = si->si_value.sival_int; 644fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 645fe4ed1e7SDmitry Chagin break; 646fe4ed1e7SDmitry Chagin 647fe4ed1e7SDmitry Chagin default: 648aa8b2011SKonstantin Belousov switch (sig) { 649aa8b2011SKonstantin Belousov case LINUX_SIGPOLL: 650aa8b2011SKonstantin Belousov /* XXX si_fd? */ 651fe4ed1e7SDmitry Chagin lsi->lsi_band = si->si_band; 652aa8b2011SKonstantin Belousov break; 653fe4ed1e7SDmitry Chagin 654aa8b2011SKonstantin Belousov case LINUX_SIGCHLD: 655fe4ed1e7SDmitry Chagin lsi->lsi_errno = 0; 656fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 657fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 658fe4ed1e7SDmitry Chagin 659fe4ed1e7SDmitry Chagin if (si->si_code == CLD_STOPPED) 6604ab7403bSDmitry Chagin lsi->lsi_status = bsd_to_linux_signal(si->si_status); 661fe4ed1e7SDmitry Chagin else if (si->si_code == CLD_CONTINUED) 6624ab7403bSDmitry Chagin lsi->lsi_status = bsd_to_linux_signal(SIGCONT); 663fe4ed1e7SDmitry Chagin else 664fe4ed1e7SDmitry Chagin lsi->lsi_status = si->si_status; 665aa8b2011SKonstantin Belousov break; 666fe4ed1e7SDmitry Chagin 667aa8b2011SKonstantin Belousov case LINUX_SIGBUS: 668aa8b2011SKonstantin Belousov case LINUX_SIGILL: 669aa8b2011SKonstantin Belousov case LINUX_SIGFPE: 670aa8b2011SKonstantin Belousov case LINUX_SIGSEGV: 671fe4ed1e7SDmitry Chagin lsi->lsi_addr = PTROUT(si->si_addr); 672aa8b2011SKonstantin Belousov break; 673fe4ed1e7SDmitry Chagin 674aa8b2011SKonstantin Belousov default: 675fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 676fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 677fe4ed1e7SDmitry Chagin if (sig >= LINUX_SIGRTMIN) { 678fe4ed1e7SDmitry Chagin lsi->lsi_int = si->si_value.sival_int; 679fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 680fe4ed1e7SDmitry Chagin } 681aa8b2011SKonstantin Belousov break; 682aa8b2011SKonstantin Belousov } 683fe4ed1e7SDmitry Chagin break; 68409d6cb0aSDmitry Chagin } 6859b44bfc5SAlexander Leidinger } 6867ac9766dSDmitry Chagin 6879c1045ffSDmitry Chagin int 6889c1045ffSDmitry Chagin lsiginfo_to_siginfo(struct thread *td, const l_siginfo_t *lsi, 6899c1045ffSDmitry Chagin siginfo_t *si, int sig) 6907ac9766dSDmitry Chagin { 6917ac9766dSDmitry Chagin 6929c1045ffSDmitry Chagin switch (lsi->lsi_code) { 6939c1045ffSDmitry Chagin case LINUX_SI_TKILL: 6949c1045ffSDmitry Chagin if (linux_kernver(td) >= LINUX_KERNVER_2006039) { 6959c1045ffSDmitry Chagin linux_msg(td, "SI_TKILL forbidden since 2.6.39"); 6969c1045ffSDmitry Chagin return (EPERM); 6979c1045ffSDmitry Chagin } 6989c1045ffSDmitry Chagin si->si_code = SI_LWP; 6999c1045ffSDmitry Chagin case LINUX_SI_QUEUE: 7009c1045ffSDmitry Chagin si->si_code = SI_QUEUE; 7019c1045ffSDmitry Chagin break; 7029c1045ffSDmitry Chagin case LINUX_SI_TIMER: 7039c1045ffSDmitry Chagin si->si_code = SI_TIMER; 7049c1045ffSDmitry Chagin break; 7059c1045ffSDmitry Chagin case LINUX_SI_MESGQ: 7069c1045ffSDmitry Chagin si->si_code = SI_MESGQ; 7079c1045ffSDmitry Chagin break; 7089c1045ffSDmitry Chagin case LINUX_SI_ASYNCIO: 7099c1045ffSDmitry Chagin si->si_code = SI_ASYNCIO; 7109c1045ffSDmitry Chagin break; 7119c1045ffSDmitry Chagin default: 7129c1045ffSDmitry Chagin si->si_code = lsi->lsi_code; 7139c1045ffSDmitry Chagin break; 7149c1045ffSDmitry Chagin } 7159c1045ffSDmitry Chagin 7169c1045ffSDmitry Chagin si->si_signo = sig; 7179c1045ffSDmitry Chagin si->si_pid = td->td_proc->p_pid; 7189c1045ffSDmitry Chagin si->si_uid = td->td_ucred->cr_ruid; 7199c1045ffSDmitry Chagin si->si_value.sival_ptr = PTRIN(lsi->lsi_value.sival_ptr); 7209c1045ffSDmitry Chagin return (0); 7217ac9766dSDmitry Chagin } 7227ac9766dSDmitry Chagin 7237ac9766dSDmitry Chagin int 7247ac9766dSDmitry Chagin linux_rt_sigqueueinfo(struct thread *td, struct linux_rt_sigqueueinfo_args *args) 7257ac9766dSDmitry Chagin { 7267ac9766dSDmitry Chagin l_siginfo_t linfo; 7277ac9766dSDmitry Chagin struct proc *p; 7287ac9766dSDmitry Chagin ksiginfo_t ksi; 7297ac9766dSDmitry Chagin int error; 7307ac9766dSDmitry Chagin int sig; 7317ac9766dSDmitry Chagin 7327ac9766dSDmitry Chagin if (!LINUX_SIG_VALID(args->sig)) 7337ac9766dSDmitry Chagin return (EINVAL); 7347ac9766dSDmitry Chagin 7357ac9766dSDmitry Chagin error = copyin(args->info, &linfo, sizeof(linfo)); 7367ac9766dSDmitry Chagin if (error != 0) 7377ac9766dSDmitry Chagin return (error); 7387ac9766dSDmitry Chagin 7397ac9766dSDmitry Chagin if (linfo.lsi_code >= 0) 7409c1045ffSDmitry Chagin /* SI_USER, SI_KERNEL */ 7417ac9766dSDmitry Chagin return (EPERM); 7427ac9766dSDmitry Chagin 7434ab7403bSDmitry Chagin sig = linux_to_bsd_signal(args->sig); 7449c1045ffSDmitry Chagin ksiginfo_init(&ksi); 7459c1045ffSDmitry Chagin error = lsiginfo_to_siginfo(td, &linfo, &ksi.ksi_info, sig); 7469c1045ffSDmitry Chagin if (error != 0) 7479c1045ffSDmitry Chagin return (error); 7487ac9766dSDmitry Chagin 7497ac9766dSDmitry Chagin error = ESRCH; 750537d0fb1SMateusz Guzik if ((p = pfind_any(args->pid)) != NULL) { 7517ac9766dSDmitry Chagin error = p_cansignal(td, p, sig); 7527ac9766dSDmitry Chagin if (error != 0) { 7537ac9766dSDmitry Chagin PROC_UNLOCK(p); 7547ac9766dSDmitry Chagin return (error); 7557ac9766dSDmitry Chagin } 7567ac9766dSDmitry Chagin error = tdsendsignal(p, NULL, sig, &ksi); 7577ac9766dSDmitry Chagin PROC_UNLOCK(p); 7587ac9766dSDmitry Chagin } 7597ac9766dSDmitry Chagin 7607ac9766dSDmitry Chagin return (error); 7617ac9766dSDmitry Chagin } 762486a06bdSDmitry Chagin 763486a06bdSDmitry Chagin int 764486a06bdSDmitry Chagin linux_rt_tgsigqueueinfo(struct thread *td, struct linux_rt_tgsigqueueinfo_args *args) 765486a06bdSDmitry Chagin { 766486a06bdSDmitry Chagin l_siginfo_t linfo; 767486a06bdSDmitry Chagin struct thread *tds; 768486a06bdSDmitry Chagin ksiginfo_t ksi; 769486a06bdSDmitry Chagin int error; 770486a06bdSDmitry Chagin int sig; 771486a06bdSDmitry Chagin 772486a06bdSDmitry Chagin if (!LINUX_SIG_VALID(args->sig)) 773486a06bdSDmitry Chagin return (EINVAL); 774486a06bdSDmitry Chagin 775486a06bdSDmitry Chagin error = copyin(args->uinfo, &linfo, sizeof(linfo)); 776486a06bdSDmitry Chagin if (error != 0) 777486a06bdSDmitry Chagin return (error); 778486a06bdSDmitry Chagin 779486a06bdSDmitry Chagin if (linfo.lsi_code >= 0) 780486a06bdSDmitry Chagin return (EPERM); 781486a06bdSDmitry Chagin 7829c1045ffSDmitry Chagin sig = linux_to_bsd_signal(args->sig); 7839c1045ffSDmitry Chagin ksiginfo_init(&ksi); 7849c1045ffSDmitry Chagin error = lsiginfo_to_siginfo(td, &linfo, &ksi.ksi_info, sig); 7859c1045ffSDmitry Chagin if (error != 0) 7869c1045ffSDmitry Chagin return (error); 7879c1045ffSDmitry Chagin 788486a06bdSDmitry Chagin tds = linux_tdfind(td, args->tid, args->tgid); 789486a06bdSDmitry Chagin if (tds == NULL) 790486a06bdSDmitry Chagin return (ESRCH); 791486a06bdSDmitry Chagin 792486a06bdSDmitry Chagin return (linux_do_tkill(td, tds, &ksi)); 793486a06bdSDmitry Chagin } 794