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); 63fe4ed1e7SDmitry Chagin 64a1ebcbfbSPeter Wemm static void 655002a60fSMarcel Moolenaar linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa) 66d66a5066SPeter Wemm { 67d5629eb2SEdward Tomasz Napierala unsigned long flags; 68956d3333SMarcel Moolenaar 69956d3333SMarcel Moolenaar linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask); 704af27623STim J. Robbins bsa->sa_handler = PTRIN(lsa->lsa_handler); 71d66a5066SPeter Wemm bsa->sa_flags = 0; 72d5629eb2SEdward Tomasz Napierala 73d5629eb2SEdward Tomasz Napierala flags = lsa->lsa_flags; 74d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) { 75d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_NOCLDSTOP; 76d66a5066SPeter Wemm bsa->sa_flags |= SA_NOCLDSTOP; 77d5629eb2SEdward Tomasz Napierala } 78d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) { 79d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_NOCLDWAIT; 8006ebbe77SMarcel Moolenaar bsa->sa_flags |= SA_NOCLDWAIT; 81d5629eb2SEdward Tomasz Napierala } 82d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_SIGINFO) { 83d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_SIGINFO; 8406ebbe77SMarcel Moolenaar bsa->sa_flags |= SA_SIGINFO; 85d5629eb2SEdward Tomasz Napierala #ifdef notyet 86d5629eb2SEdward Tomasz Napierala /* 87d5629eb2SEdward Tomasz Napierala * XXX: We seem to be missing code to convert 88d5629eb2SEdward Tomasz Napierala * some of the fields in ucontext_t. 89d5629eb2SEdward Tomasz Napierala */ 90d5629eb2SEdward Tomasz Napierala linux_msg(curthread, 91d5629eb2SEdward Tomasz Napierala "partially unsupported sigaction flag SA_SIGINFO"); 92d5629eb2SEdward Tomasz Napierala #endif 93d5629eb2SEdward Tomasz Napierala } 94d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_RESTORER) { 95d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_RESTORER; 96d5629eb2SEdward Tomasz Napierala /* XXX: We might want to handle it; see Linux sigreturn(2). */ 97d5629eb2SEdward Tomasz Napierala } 98d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_ONSTACK) { 99d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_ONSTACK; 100d66a5066SPeter Wemm bsa->sa_flags |= SA_ONSTACK; 101d5629eb2SEdward Tomasz Napierala } 102d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_RESTART) { 103d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_RESTART; 104d66a5066SPeter Wemm bsa->sa_flags |= SA_RESTART; 105d5629eb2SEdward Tomasz Napierala } 1069bc42c18SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_INTERRUPT) { 1079bc42c18SEdward Tomasz Napierala flags &= ~LINUX_SA_INTERRUPT; 1089bc42c18SEdward Tomasz Napierala /* Documented to be a "historical no-op". */ 1099bc42c18SEdward Tomasz Napierala } 110d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_ONESHOT) { 111d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_ONESHOT; 112d66a5066SPeter Wemm bsa->sa_flags |= SA_RESETHAND; 113d5629eb2SEdward Tomasz Napierala } 114d5629eb2SEdward Tomasz Napierala if (lsa->lsa_flags & LINUX_SA_NOMASK) { 115d5629eb2SEdward Tomasz Napierala flags &= ~LINUX_SA_NOMASK; 116d66a5066SPeter Wemm bsa->sa_flags |= SA_NODEFER; 117d66a5066SPeter Wemm } 118d66a5066SPeter Wemm 119d5629eb2SEdward Tomasz Napierala if (flags != 0) 120d5629eb2SEdward Tomasz Napierala linux_msg(curthread, "unsupported sigaction flag %#lx", flags); 121d5629eb2SEdward Tomasz Napierala } 122d5629eb2SEdward Tomasz Napierala 123a1ebcbfbSPeter Wemm static void 1245002a60fSMarcel Moolenaar bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa) 125d66a5066SPeter Wemm { 126956d3333SMarcel Moolenaar 127956d3333SMarcel Moolenaar bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask); 1281997c537SDavid E. O'Brien #ifdef COMPAT_LINUX32 1294af27623STim J. Robbins lsa->lsa_handler = (uintptr_t)bsa->sa_handler; 1304af27623STim J. Robbins #else 1318f437f44SMartin Cracauer lsa->lsa_handler = bsa->sa_handler; 1324af27623STim J. Robbins #endif 1334af27623STim J. Robbins lsa->lsa_restorer = 0; /* unsupported */ 1348f437f44SMartin Cracauer lsa->lsa_flags = 0; 135d66a5066SPeter Wemm if (bsa->sa_flags & SA_NOCLDSTOP) 1368f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_NOCLDSTOP; 13706ebbe77SMarcel Moolenaar if (bsa->sa_flags & SA_NOCLDWAIT) 13806ebbe77SMarcel Moolenaar lsa->lsa_flags |= LINUX_SA_NOCLDWAIT; 13906ebbe77SMarcel Moolenaar if (bsa->sa_flags & SA_SIGINFO) 14006ebbe77SMarcel Moolenaar lsa->lsa_flags |= LINUX_SA_SIGINFO; 141d66a5066SPeter Wemm if (bsa->sa_flags & SA_ONSTACK) 1428f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_ONSTACK; 143d66a5066SPeter Wemm if (bsa->sa_flags & SA_RESTART) 1448f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_RESTART; 145d66a5066SPeter Wemm if (bsa->sa_flags & SA_RESETHAND) 1468f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_ONESHOT; 147d66a5066SPeter Wemm if (bsa->sa_flags & SA_NODEFER) 1488f437f44SMartin Cracauer lsa->lsa_flags |= LINUX_SA_NOMASK; 149d66a5066SPeter Wemm } 150c21dee17SSøren Schmidt 151ba9ef45bSMarcel Moolenaar int 152b40ce416SJulian Elischer linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa, 1535002a60fSMarcel Moolenaar l_sigaction_t *linux_osa) 15406ebbe77SMarcel Moolenaar { 155206a5d3aSIan Dowse struct sigaction act, oact, *nsa, *osa; 156206a5d3aSIan Dowse int error, sig; 15706ebbe77SMarcel Moolenaar 158687c23beSAlexander Leidinger if (!LINUX_SIG_VALID(linux_sig)) 159956d3333SMarcel Moolenaar return (EINVAL); 16006ebbe77SMarcel Moolenaar 161206a5d3aSIan Dowse osa = (linux_osa != NULL) ? &oact : NULL; 162956d3333SMarcel Moolenaar if (linux_nsa != NULL) { 163206a5d3aSIan Dowse nsa = &act; 164ec99e322SMarcel Moolenaar linux_to_bsd_sigaction(linux_nsa, nsa); 165206a5d3aSIan Dowse } else 16606ebbe77SMarcel Moolenaar nsa = NULL; 1674ab7403bSDmitry Chagin sig = linux_to_bsd_signal(linux_sig); 168956d3333SMarcel Moolenaar 169206a5d3aSIan Dowse error = kern_sigaction(td, sig, nsa, osa, 0); 17006ebbe77SMarcel Moolenaar if (error) 171956d3333SMarcel Moolenaar return (error); 17206ebbe77SMarcel Moolenaar 173ec99e322SMarcel Moolenaar if (linux_osa != NULL) 174ec99e322SMarcel Moolenaar bsd_to_linux_sigaction(osa, linux_osa); 17506ebbe77SMarcel Moolenaar 176956d3333SMarcel Moolenaar return (0); 17706ebbe77SMarcel Moolenaar } 17806ebbe77SMarcel Moolenaar 1797f8f1d7fSDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 180c21dee17SSøren Schmidt int 181b40ce416SJulian Elischer linux_signal(struct thread *td, struct linux_signal_args *args) 182d66a5066SPeter Wemm { 1835002a60fSMarcel Moolenaar l_sigaction_t nsa, osa; 184d66a5066SPeter Wemm int error; 185d66a5066SPeter Wemm 18606ebbe77SMarcel Moolenaar nsa.lsa_handler = args->handler; 18706ebbe77SMarcel Moolenaar nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK; 188956d3333SMarcel Moolenaar LINUX_SIGEMPTYSET(nsa.lsa_mask); 189d66a5066SPeter Wemm 190b40ce416SJulian Elischer error = linux_do_sigaction(td, args->sig, &nsa, &osa); 1914af27623STim J. Robbins td->td_retval[0] = (int)(intptr_t)osa.lsa_handler; 192d66a5066SPeter Wemm 193956d3333SMarcel Moolenaar return (error); 194d66a5066SPeter Wemm } 1957f8f1d7fSDmitry Chagin #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 196d66a5066SPeter Wemm 197c21dee17SSøren Schmidt int 198b40ce416SJulian Elischer linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args) 199c21dee17SSøren Schmidt { 2005002a60fSMarcel Moolenaar l_sigaction_t nsa, osa; 20106ebbe77SMarcel Moolenaar int error; 202c21dee17SSøren Schmidt 2035002a60fSMarcel Moolenaar if (args->sigsetsize != sizeof(l_sigset_t)) 204956d3333SMarcel Moolenaar return (EINVAL); 20506ebbe77SMarcel Moolenaar 206956d3333SMarcel Moolenaar if (args->act != NULL) { 2075002a60fSMarcel Moolenaar error = copyin(args->act, &nsa, sizeof(l_sigaction_t)); 20806ebbe77SMarcel Moolenaar if (error) 209956d3333SMarcel Moolenaar return (error); 21006ebbe77SMarcel Moolenaar } 21106ebbe77SMarcel Moolenaar 212b40ce416SJulian Elischer error = linux_do_sigaction(td, args->sig, 21306ebbe77SMarcel Moolenaar args->act ? &nsa : NULL, 21406ebbe77SMarcel Moolenaar args->oact ? &osa : NULL); 21506ebbe77SMarcel Moolenaar 216956d3333SMarcel Moolenaar if (args->oact != NULL && !error) { 2175002a60fSMarcel Moolenaar error = copyout(&osa, args->oact, sizeof(l_sigaction_t)); 21806ebbe77SMarcel Moolenaar } 21906ebbe77SMarcel Moolenaar 220956d3333SMarcel Moolenaar return (error); 22106ebbe77SMarcel Moolenaar } 22206ebbe77SMarcel Moolenaar 22306ebbe77SMarcel Moolenaar static int 224b40ce416SJulian Elischer linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new, 2255002a60fSMarcel Moolenaar l_sigset_t *old) 22606ebbe77SMarcel Moolenaar { 227fe8cdcaeSJohn Baldwin sigset_t omask, nmask; 228fe8cdcaeSJohn Baldwin sigset_t *nmaskp; 229216af822SJohn Baldwin int error; 23006ebbe77SMarcel Moolenaar 231b40ce416SJulian Elischer td->td_retval[0] = 0; 232d66a5066SPeter Wemm 23319dde5cdSJohn Baldwin switch (how) { 23419dde5cdSJohn Baldwin case LINUX_SIG_BLOCK: 23519dde5cdSJohn Baldwin how = SIG_BLOCK; 23619dde5cdSJohn Baldwin break; 23719dde5cdSJohn Baldwin case LINUX_SIG_UNBLOCK: 23819dde5cdSJohn Baldwin how = SIG_UNBLOCK; 23919dde5cdSJohn Baldwin break; 24019dde5cdSJohn Baldwin case LINUX_SIG_SETMASK: 24119dde5cdSJohn Baldwin how = SIG_SETMASK; 24219dde5cdSJohn Baldwin break; 24319dde5cdSJohn Baldwin default: 24419dde5cdSJohn Baldwin return (EINVAL); 24519dde5cdSJohn Baldwin } 24606ebbe77SMarcel Moolenaar if (new != NULL) { 247fe8cdcaeSJohn Baldwin linux_to_bsd_sigset(new, &nmask); 248fe8cdcaeSJohn Baldwin nmaskp = &nmask; 249fe8cdcaeSJohn Baldwin } else 250fe8cdcaeSJohn Baldwin nmaskp = NULL; 25119dde5cdSJohn Baldwin error = kern_sigprocmask(td, how, nmaskp, &omask, 0); 2522f7ed219SJohn Baldwin if (error == 0 && old != NULL) 253fe8cdcaeSJohn Baldwin bsd_to_linux_sigset(&omask, old); 25406ebbe77SMarcel Moolenaar 255956d3333SMarcel Moolenaar return (error); 25606ebbe77SMarcel Moolenaar } 25706ebbe77SMarcel Moolenaar 2587f8f1d7fSDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 25906ebbe77SMarcel Moolenaar int 260b40ce416SJulian Elischer linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args) 26106ebbe77SMarcel Moolenaar { 2625002a60fSMarcel Moolenaar l_osigset_t mask; 2635002a60fSMarcel Moolenaar l_sigset_t set, oset; 26406ebbe77SMarcel Moolenaar int error; 26506ebbe77SMarcel Moolenaar 26606ebbe77SMarcel Moolenaar if (args->mask != NULL) { 2675002a60fSMarcel Moolenaar error = copyin(args->mask, &mask, sizeof(l_osigset_t)); 26806ebbe77SMarcel Moolenaar if (error) 269956d3333SMarcel Moolenaar return (error); 270956d3333SMarcel Moolenaar LINUX_SIGEMPTYSET(set); 2714ab7403bSDmitry Chagin set.__mask = mask; 27206ebbe77SMarcel Moolenaar } 27306ebbe77SMarcel Moolenaar 274b40ce416SJulian Elischer error = linux_do_sigprocmask(td, args->how, 275956d3333SMarcel Moolenaar args->mask ? &set : NULL, 276956d3333SMarcel Moolenaar args->omask ? &oset : NULL); 27706ebbe77SMarcel Moolenaar 278956d3333SMarcel Moolenaar if (args->omask != NULL && !error) { 2794ab7403bSDmitry Chagin mask = oset.__mask; 2805002a60fSMarcel Moolenaar error = copyout(&mask, args->omask, sizeof(l_osigset_t)); 28106ebbe77SMarcel Moolenaar } 28206ebbe77SMarcel Moolenaar 283956d3333SMarcel Moolenaar return (error); 28406ebbe77SMarcel Moolenaar } 2857f8f1d7fSDmitry Chagin #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 28606ebbe77SMarcel Moolenaar 28706ebbe77SMarcel Moolenaar int 288b40ce416SJulian Elischer linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args) 28906ebbe77SMarcel Moolenaar { 2905002a60fSMarcel Moolenaar l_sigset_t set, oset; 29106ebbe77SMarcel Moolenaar int error; 29206ebbe77SMarcel Moolenaar 2935002a60fSMarcel Moolenaar if (args->sigsetsize != sizeof(l_sigset_t)) 294340f4a8dSEd Maste return (EINVAL); 29506ebbe77SMarcel Moolenaar 29606ebbe77SMarcel Moolenaar if (args->mask != NULL) { 2975002a60fSMarcel Moolenaar error = copyin(args->mask, &set, sizeof(l_sigset_t)); 29806ebbe77SMarcel Moolenaar if (error) 299956d3333SMarcel Moolenaar return (error); 30006ebbe77SMarcel Moolenaar } 30106ebbe77SMarcel Moolenaar 302b40ce416SJulian Elischer error = linux_do_sigprocmask(td, args->how, 303956d3333SMarcel Moolenaar args->mask ? &set : NULL, 304956d3333SMarcel Moolenaar args->omask ? &oset : NULL); 30506ebbe77SMarcel Moolenaar 306956d3333SMarcel Moolenaar if (args->omask != NULL && !error) { 3075002a60fSMarcel Moolenaar error = copyout(&oset, args->omask, sizeof(l_sigset_t)); 30806ebbe77SMarcel Moolenaar } 30906ebbe77SMarcel Moolenaar 310956d3333SMarcel Moolenaar return (error); 311c21dee17SSøren Schmidt } 312c21dee17SSøren Schmidt 3137f8f1d7fSDmitry Chagin #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) 314c21dee17SSøren Schmidt int 315b40ce416SJulian Elischer linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args) 316c21dee17SSøren Schmidt { 317b40ce416SJulian Elischer struct proc *p = td->td_proc; 3185002a60fSMarcel Moolenaar l_sigset_t mask; 319956d3333SMarcel Moolenaar 320216af822SJohn Baldwin PROC_LOCK(p); 3214093529dSJeff Roberson bsd_to_linux_sigset(&td->td_sigmask, &mask); 322216af822SJohn Baldwin PROC_UNLOCK(p); 3234ab7403bSDmitry Chagin td->td_retval[0] = mask.__mask; 324956d3333SMarcel Moolenaar return (0); 325c21dee17SSøren Schmidt } 326c21dee17SSøren Schmidt 327c21dee17SSøren Schmidt int 328b40ce416SJulian Elischer linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args) 329c21dee17SSøren Schmidt { 330b40ce416SJulian Elischer struct proc *p = td->td_proc; 3315002a60fSMarcel Moolenaar l_sigset_t lset; 332956d3333SMarcel Moolenaar sigset_t bset; 333c21dee17SSøren Schmidt 334216af822SJohn Baldwin PROC_LOCK(p); 3354093529dSJeff Roberson bsd_to_linux_sigset(&td->td_sigmask, &lset); 3364ab7403bSDmitry Chagin td->td_retval[0] = lset.__mask; 337956d3333SMarcel Moolenaar LINUX_SIGEMPTYSET(lset); 3384ab7403bSDmitry Chagin lset.__mask = args->mask; 339956d3333SMarcel Moolenaar linux_to_bsd_sigset(&lset, &bset); 3404093529dSJeff Roberson td->td_sigmask = bset; 3414093529dSJeff Roberson SIG_CANTMASK(td->td_sigmask); 3424093529dSJeff Roberson signotify(td); 343216af822SJohn Baldwin PROC_UNLOCK(p); 344956d3333SMarcel Moolenaar return (0); 345c21dee17SSøren Schmidt } 346c21dee17SSøren Schmidt 347c21dee17SSøren Schmidt int 348b40ce416SJulian Elischer linux_sigpending(struct thread *td, struct linux_sigpending_args *args) 349c21dee17SSøren Schmidt { 350b40ce416SJulian Elischer struct proc *p = td->td_proc; 351956d3333SMarcel Moolenaar sigset_t bset; 3525002a60fSMarcel Moolenaar l_sigset_t lset; 3535002a60fSMarcel Moolenaar l_osigset_t mask; 354c21dee17SSøren Schmidt 355216af822SJohn Baldwin PROC_LOCK(p); 3561d9c5696SJuli Mallett bset = p->p_siglist; 3574093529dSJeff Roberson SIGSETOR(bset, td->td_siglist); 3584093529dSJeff Roberson SIGSETAND(bset, td->td_sigmask); 359216af822SJohn Baldwin PROC_UNLOCK(p); 3609d8643ecSJohn Baldwin bsd_to_linux_sigset(&bset, &lset); 3614ab7403bSDmitry Chagin mask = lset.__mask; 362956d3333SMarcel Moolenaar return (copyout(&mask, args->mask, sizeof(mask))); 363c21dee17SSøren Schmidt } 3647f8f1d7fSDmitry Chagin #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ 36517138b61SAlexander Leidinger 36617138b61SAlexander Leidinger /* 36717138b61SAlexander Leidinger * MPSAFE 36817138b61SAlexander Leidinger */ 36917138b61SAlexander Leidinger int 37017138b61SAlexander Leidinger linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args) 37117138b61SAlexander Leidinger { 37217138b61SAlexander Leidinger struct proc *p = td->td_proc; 37317138b61SAlexander Leidinger sigset_t bset; 37417138b61SAlexander Leidinger l_sigset_t lset; 37517138b61SAlexander Leidinger 37617138b61SAlexander Leidinger if (args->sigsetsize > sizeof(lset)) 377340f4a8dSEd Maste return (EINVAL); 37817138b61SAlexander Leidinger /* NOT REACHED */ 37917138b61SAlexander Leidinger 38017138b61SAlexander Leidinger PROC_LOCK(p); 38117138b61SAlexander Leidinger bset = p->p_siglist; 38217138b61SAlexander Leidinger SIGSETOR(bset, td->td_siglist); 38317138b61SAlexander Leidinger SIGSETAND(bset, td->td_sigmask); 38417138b61SAlexander Leidinger PROC_UNLOCK(p); 38517138b61SAlexander Leidinger bsd_to_linux_sigset(&bset, &lset); 38617138b61SAlexander Leidinger return (copyout(&lset, args->set, args->sigsetsize)); 38717138b61SAlexander Leidinger } 388c21dee17SSøren Schmidt 389c9447c75SAlexander Leidinger /* 390c9447c75SAlexander Leidinger * MPSAFE 391c9447c75SAlexander Leidinger */ 392c9447c75SAlexander Leidinger int 393c9447c75SAlexander Leidinger linux_rt_sigtimedwait(struct thread *td, 394c9447c75SAlexander Leidinger struct linux_rt_sigtimedwait_args *args) 395c9447c75SAlexander Leidinger { 396f3481dd9SDmitry Chagin int error, sig; 397c9447c75SAlexander Leidinger struct timespec ts, *tsa; 3980f8dab45SDmitry Chagin struct l_timespec lts; 399c9447c75SAlexander Leidinger l_sigset_t lset; 400c9447c75SAlexander Leidinger sigset_t bset; 401*f4e80108SDmitry Chagin l_siginfo_t lsi; 402*f4e80108SDmitry Chagin ksiginfo_t ksi; 403c9447c75SAlexander Leidinger 404c9447c75SAlexander Leidinger if (args->sigsetsize != sizeof(l_sigset_t)) 405c9447c75SAlexander Leidinger return (EINVAL); 406c9447c75SAlexander Leidinger 407c9447c75SAlexander Leidinger if ((error = copyin(args->mask, &lset, sizeof(lset)))) 408c9447c75SAlexander Leidinger return (error); 409c9447c75SAlexander Leidinger linux_to_bsd_sigset(&lset, &bset); 410c9447c75SAlexander Leidinger 411c9447c75SAlexander Leidinger tsa = NULL; 412c9447c75SAlexander Leidinger if (args->timeout) { 4130f8dab45SDmitry Chagin if ((error = copyin(args->timeout, <s, sizeof(lts)))) 414c9447c75SAlexander Leidinger return (error); 4150f8dab45SDmitry Chagin error = linux_to_native_timespec(&ts, <s); 4160f8dab45SDmitry Chagin if (error != 0) 4170f8dab45SDmitry Chagin return (error); 418c9447c75SAlexander Leidinger tsa = &ts; 4190f8dab45SDmitry Chagin } else 4200f8dab45SDmitry Chagin tsa = NULL; 4210f8dab45SDmitry Chagin 422*f4e80108SDmitry Chagin error = kern_sigtimedwait(td, bset, &ksi, tsa); 423c9447c75SAlexander Leidinger if (error) 424c9447c75SAlexander Leidinger return (error); 425c9447c75SAlexander Leidinger 426*f4e80108SDmitry Chagin sig = bsd_to_linux_signal(ksi.ksi_signo); 427f3481dd9SDmitry Chagin 428c9447c75SAlexander Leidinger if (args->ptr) { 429*f4e80108SDmitry Chagin memset(&lsi, 0, sizeof(lsi)); 430*f4e80108SDmitry Chagin siginfo_to_lsiginfo(&ksi.ksi_info, &lsi, sig); 431*f4e80108SDmitry Chagin error = copyout(&lsi, args->ptr, sizeof(lsi)); 432c9447c75SAlexander Leidinger } 433f3481dd9SDmitry Chagin if (error == 0) 434f3481dd9SDmitry Chagin td->td_retval[0] = sig; 435c9447c75SAlexander Leidinger 436c9447c75SAlexander Leidinger return (error); 437c9447c75SAlexander Leidinger } 438c9447c75SAlexander Leidinger 439c21dee17SSøren Schmidt int 440b40ce416SJulian Elischer linux_kill(struct thread *td, struct linux_kill_args *args) 441c21dee17SSøren Schmidt { 44234ad5ac2SEdward Tomasz Napierala int l_signum; 443c21dee17SSøren Schmidt 444956d3333SMarcel Moolenaar /* 445956d3333SMarcel Moolenaar * Allow signal 0 as a means to check for privileges 446956d3333SMarcel Moolenaar */ 44764742216SAlexander Leidinger if (!LINUX_SIG_VALID(args->signum) && args->signum != 0) 4489a6a64d3SDmitry Chagin return (EINVAL); 449956d3333SMarcel Moolenaar 4504ab7403bSDmitry Chagin if (args->signum > 0) 45134ad5ac2SEdward Tomasz Napierala l_signum = linux_to_bsd_signal(args->signum); 452956d3333SMarcel Moolenaar else 45334ad5ac2SEdward Tomasz Napierala l_signum = 0; 454956d3333SMarcel Moolenaar 45534ad5ac2SEdward Tomasz Napierala return (kern_kill(td, args->pid, l_signum)); 456c21dee17SSøren Schmidt } 4579b44bfc5SAlexander Leidinger 458aa8b2011SKonstantin Belousov static int 45981338031SDmitry Chagin linux_do_tkill(struct thread *td, struct thread *tdt, ksiginfo_t *ksi) 460aa8b2011SKonstantin Belousov { 461aa8b2011SKonstantin Belousov struct proc *p; 462aa8b2011SKonstantin Belousov int error; 463aa8b2011SKonstantin Belousov 46481338031SDmitry Chagin p = tdt->td_proc; 46581338031SDmitry Chagin AUDIT_ARG_SIGNUM(ksi->ksi_signo); 46681338031SDmitry Chagin AUDIT_ARG_PID(p->p_pid); 46714961ba7SRobert Watson AUDIT_ARG_PROCESS(p); 46881338031SDmitry Chagin 46981338031SDmitry Chagin error = p_cansignal(td, p, ksi->ksi_signo); 47081338031SDmitry Chagin if (error != 0 || ksi->ksi_signo == 0) 471aa8b2011SKonstantin Belousov goto out; 472aa8b2011SKonstantin Belousov 47381338031SDmitry Chagin tdksignal(tdt, ksi->ksi_signo, ksi); 474aa8b2011SKonstantin Belousov 475aa8b2011SKonstantin Belousov out: 476aa8b2011SKonstantin Belousov PROC_UNLOCK(p); 477aa8b2011SKonstantin Belousov return (error); 478aa8b2011SKonstantin Belousov } 479aa8b2011SKonstantin Belousov 4809b44bfc5SAlexander Leidinger int 4819b44bfc5SAlexander Leidinger linux_tgkill(struct thread *td, struct linux_tgkill_args *args) 4829b44bfc5SAlexander Leidinger { 48381338031SDmitry Chagin struct thread *tdt; 48481338031SDmitry Chagin ksiginfo_t ksi; 48581338031SDmitry Chagin int sig; 4869b44bfc5SAlexander Leidinger 487aa8b2011SKonstantin Belousov if (args->pid <= 0 || args->tgid <=0) 488aa8b2011SKonstantin Belousov return (EINVAL); 4899b44bfc5SAlexander Leidinger 49081338031SDmitry Chagin /* 49181338031SDmitry Chagin * Allow signal 0 as a means to check for privileges 49281338031SDmitry Chagin */ 49381338031SDmitry Chagin if (!LINUX_SIG_VALID(args->sig) && args->sig != 0) 49481338031SDmitry Chagin return (EINVAL); 49581338031SDmitry Chagin 4964ab7403bSDmitry Chagin if (args->sig > 0) 4974ab7403bSDmitry Chagin sig = linux_to_bsd_signal(args->sig); 49881338031SDmitry Chagin else 4994ab7403bSDmitry Chagin sig = 0; 50081338031SDmitry Chagin 50181338031SDmitry Chagin tdt = linux_tdfind(td, args->pid, args->tgid); 50281338031SDmitry Chagin if (tdt == NULL) 50381338031SDmitry Chagin return (ESRCH); 50481338031SDmitry Chagin 50581338031SDmitry Chagin ksiginfo_init(&ksi); 50681338031SDmitry Chagin ksi.ksi_signo = sig; 507fe4ed1e7SDmitry Chagin ksi.ksi_code = SI_LWP; 50881338031SDmitry Chagin ksi.ksi_errno = 0; 50981338031SDmitry Chagin ksi.ksi_pid = td->td_proc->p_pid; 51081338031SDmitry Chagin ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 51181338031SDmitry Chagin return (linux_do_tkill(td, tdt, &ksi)); 5129b44bfc5SAlexander Leidinger } 5139b44bfc5SAlexander Leidinger 51481338031SDmitry Chagin /* 51581338031SDmitry Chagin * Deprecated since 2.5.75. Replaced by tgkill(). 51681338031SDmitry Chagin */ 5179b44bfc5SAlexander Leidinger int 5189b44bfc5SAlexander Leidinger linux_tkill(struct thread *td, struct linux_tkill_args *args) 5199b44bfc5SAlexander Leidinger { 52081338031SDmitry Chagin struct thread *tdt; 52181338031SDmitry Chagin ksiginfo_t ksi; 52281338031SDmitry Chagin int sig; 52381338031SDmitry Chagin 524aa8b2011SKonstantin Belousov if (args->tid <= 0) 525aa8b2011SKonstantin Belousov return (EINVAL); 5269b44bfc5SAlexander Leidinger 52781338031SDmitry Chagin if (!LINUX_SIG_VALID(args->sig)) 52881338031SDmitry Chagin return (EINVAL); 52981338031SDmitry Chagin 5304ab7403bSDmitry Chagin sig = linux_to_bsd_signal(args->sig); 53181338031SDmitry Chagin 53281338031SDmitry Chagin tdt = linux_tdfind(td, args->tid, -1); 53381338031SDmitry Chagin if (tdt == NULL) 53481338031SDmitry Chagin return (ESRCH); 53581338031SDmitry Chagin 53681338031SDmitry Chagin ksiginfo_init(&ksi); 53781338031SDmitry Chagin ksi.ksi_signo = sig; 538fe4ed1e7SDmitry Chagin ksi.ksi_code = SI_LWP; 53981338031SDmitry Chagin ksi.ksi_errno = 0; 54081338031SDmitry Chagin ksi.ksi_pid = td->td_proc->p_pid; 54181338031SDmitry Chagin ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid; 54281338031SDmitry Chagin return (linux_do_tkill(td, tdt, &ksi)); 543aa8b2011SKonstantin Belousov } 544aa8b2011SKonstantin Belousov 545fe4ed1e7SDmitry Chagin static void 546fe4ed1e7SDmitry Chagin sicode_to_lsicode(int si_code, int *lsi_code) 547fe4ed1e7SDmitry Chagin { 548fe4ed1e7SDmitry Chagin 549fe4ed1e7SDmitry Chagin switch (si_code) { 550fe4ed1e7SDmitry Chagin case SI_USER: 551fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_USER; 552fe4ed1e7SDmitry Chagin break; 553fe4ed1e7SDmitry Chagin case SI_KERNEL: 554fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_KERNEL; 555fe4ed1e7SDmitry Chagin break; 556fe4ed1e7SDmitry Chagin case SI_QUEUE: 557fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_QUEUE; 558fe4ed1e7SDmitry Chagin break; 559fe4ed1e7SDmitry Chagin case SI_TIMER: 560fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_TIMER; 561fe4ed1e7SDmitry Chagin break; 562fe4ed1e7SDmitry Chagin case SI_MESGQ: 563fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_MESGQ; 564fe4ed1e7SDmitry Chagin break; 565fe4ed1e7SDmitry Chagin case SI_ASYNCIO: 566fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_ASYNCIO; 567fe4ed1e7SDmitry Chagin break; 568fe4ed1e7SDmitry Chagin case SI_LWP: 569fe4ed1e7SDmitry Chagin *lsi_code = LINUX_SI_TKILL; 570fe4ed1e7SDmitry Chagin break; 571fe4ed1e7SDmitry Chagin default: 572fe4ed1e7SDmitry Chagin *lsi_code = si_code; 573fe4ed1e7SDmitry Chagin break; 574fe4ed1e7SDmitry Chagin } 575fe4ed1e7SDmitry Chagin } 576fe4ed1e7SDmitry Chagin 577fe4ed1e7SDmitry Chagin void 578fe4ed1e7SDmitry Chagin siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig) 579fe4ed1e7SDmitry Chagin { 580fe4ed1e7SDmitry Chagin 581fe4ed1e7SDmitry Chagin /* sig alredy converted */ 582fe4ed1e7SDmitry Chagin lsi->lsi_signo = sig; 583fe4ed1e7SDmitry Chagin sicode_to_lsicode(si->si_code, &lsi->lsi_code); 584fe4ed1e7SDmitry Chagin 585fe4ed1e7SDmitry Chagin switch (si->si_code) { 586fe4ed1e7SDmitry Chagin case SI_LWP: 587fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 588fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 589fe4ed1e7SDmitry Chagin break; 590fe4ed1e7SDmitry Chagin 591fe4ed1e7SDmitry Chagin case SI_TIMER: 592fe4ed1e7SDmitry Chagin lsi->lsi_int = si->si_value.sival_int; 593fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 594fe4ed1e7SDmitry Chagin lsi->lsi_tid = si->si_timerid; 595fe4ed1e7SDmitry Chagin break; 596fe4ed1e7SDmitry Chagin 597fe4ed1e7SDmitry Chagin case SI_QUEUE: 598fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 599fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 600fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 601fe4ed1e7SDmitry Chagin break; 602fe4ed1e7SDmitry Chagin 603fe4ed1e7SDmitry Chagin case SI_ASYNCIO: 604fe4ed1e7SDmitry Chagin lsi->lsi_int = si->si_value.sival_int; 605fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 606fe4ed1e7SDmitry Chagin break; 607fe4ed1e7SDmitry Chagin 608fe4ed1e7SDmitry Chagin default: 609aa8b2011SKonstantin Belousov switch (sig) { 610aa8b2011SKonstantin Belousov case LINUX_SIGPOLL: 611aa8b2011SKonstantin Belousov /* XXX si_fd? */ 612fe4ed1e7SDmitry Chagin lsi->lsi_band = si->si_band; 613aa8b2011SKonstantin Belousov break; 614fe4ed1e7SDmitry Chagin 615aa8b2011SKonstantin Belousov case LINUX_SIGCHLD: 616fe4ed1e7SDmitry Chagin lsi->lsi_errno = 0; 617fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 618fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 619fe4ed1e7SDmitry Chagin 620fe4ed1e7SDmitry Chagin if (si->si_code == CLD_STOPPED) 6214ab7403bSDmitry Chagin lsi->lsi_status = bsd_to_linux_signal(si->si_status); 622fe4ed1e7SDmitry Chagin else if (si->si_code == CLD_CONTINUED) 6234ab7403bSDmitry Chagin lsi->lsi_status = bsd_to_linux_signal(SIGCONT); 624fe4ed1e7SDmitry Chagin else 625fe4ed1e7SDmitry Chagin lsi->lsi_status = si->si_status; 626aa8b2011SKonstantin Belousov break; 627fe4ed1e7SDmitry Chagin 628aa8b2011SKonstantin Belousov case LINUX_SIGBUS: 629aa8b2011SKonstantin Belousov case LINUX_SIGILL: 630aa8b2011SKonstantin Belousov case LINUX_SIGFPE: 631aa8b2011SKonstantin Belousov case LINUX_SIGSEGV: 632fe4ed1e7SDmitry Chagin lsi->lsi_addr = PTROUT(si->si_addr); 633aa8b2011SKonstantin Belousov break; 634fe4ed1e7SDmitry Chagin 635aa8b2011SKonstantin Belousov default: 636fe4ed1e7SDmitry Chagin lsi->lsi_pid = si->si_pid; 637fe4ed1e7SDmitry Chagin lsi->lsi_uid = si->si_uid; 638fe4ed1e7SDmitry Chagin if (sig >= LINUX_SIGRTMIN) { 639fe4ed1e7SDmitry Chagin lsi->lsi_int = si->si_value.sival_int; 640fe4ed1e7SDmitry Chagin lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr); 641fe4ed1e7SDmitry Chagin } 642aa8b2011SKonstantin Belousov break; 643aa8b2011SKonstantin Belousov } 644fe4ed1e7SDmitry Chagin break; 64509d6cb0aSDmitry Chagin } 6469b44bfc5SAlexander Leidinger } 6477ac9766dSDmitry Chagin 6489c1045ffSDmitry Chagin int 6499c1045ffSDmitry Chagin lsiginfo_to_siginfo(struct thread *td, const l_siginfo_t *lsi, 6509c1045ffSDmitry Chagin siginfo_t *si, int sig) 6517ac9766dSDmitry Chagin { 6527ac9766dSDmitry Chagin 6539c1045ffSDmitry Chagin switch (lsi->lsi_code) { 6549c1045ffSDmitry Chagin case LINUX_SI_TKILL: 6559c1045ffSDmitry Chagin if (linux_kernver(td) >= LINUX_KERNVER_2006039) { 6569c1045ffSDmitry Chagin linux_msg(td, "SI_TKILL forbidden since 2.6.39"); 6579c1045ffSDmitry Chagin return (EPERM); 6589c1045ffSDmitry Chagin } 6599c1045ffSDmitry Chagin si->si_code = SI_LWP; 6609c1045ffSDmitry Chagin case LINUX_SI_QUEUE: 6619c1045ffSDmitry Chagin si->si_code = SI_QUEUE; 6629c1045ffSDmitry Chagin break; 6639c1045ffSDmitry Chagin case LINUX_SI_TIMER: 6649c1045ffSDmitry Chagin si->si_code = SI_TIMER; 6659c1045ffSDmitry Chagin break; 6669c1045ffSDmitry Chagin case LINUX_SI_MESGQ: 6679c1045ffSDmitry Chagin si->si_code = SI_MESGQ; 6689c1045ffSDmitry Chagin break; 6699c1045ffSDmitry Chagin case LINUX_SI_ASYNCIO: 6709c1045ffSDmitry Chagin si->si_code = SI_ASYNCIO; 6719c1045ffSDmitry Chagin break; 6729c1045ffSDmitry Chagin default: 6739c1045ffSDmitry Chagin si->si_code = lsi->lsi_code; 6749c1045ffSDmitry Chagin break; 6759c1045ffSDmitry Chagin } 6769c1045ffSDmitry Chagin 6779c1045ffSDmitry Chagin si->si_signo = sig; 6789c1045ffSDmitry Chagin si->si_pid = td->td_proc->p_pid; 6799c1045ffSDmitry Chagin si->si_uid = td->td_ucred->cr_ruid; 6809c1045ffSDmitry Chagin si->si_value.sival_ptr = PTRIN(lsi->lsi_value.sival_ptr); 6819c1045ffSDmitry Chagin return (0); 6827ac9766dSDmitry Chagin } 6837ac9766dSDmitry Chagin 6847ac9766dSDmitry Chagin int 6857ac9766dSDmitry Chagin linux_rt_sigqueueinfo(struct thread *td, struct linux_rt_sigqueueinfo_args *args) 6867ac9766dSDmitry Chagin { 6877ac9766dSDmitry Chagin l_siginfo_t linfo; 6887ac9766dSDmitry Chagin struct proc *p; 6897ac9766dSDmitry Chagin ksiginfo_t ksi; 6907ac9766dSDmitry Chagin int error; 6917ac9766dSDmitry Chagin int sig; 6927ac9766dSDmitry Chagin 6937ac9766dSDmitry Chagin if (!LINUX_SIG_VALID(args->sig)) 6947ac9766dSDmitry Chagin return (EINVAL); 6957ac9766dSDmitry Chagin 6967ac9766dSDmitry Chagin error = copyin(args->info, &linfo, sizeof(linfo)); 6977ac9766dSDmitry Chagin if (error != 0) 6987ac9766dSDmitry Chagin return (error); 6997ac9766dSDmitry Chagin 7007ac9766dSDmitry Chagin if (linfo.lsi_code >= 0) 7019c1045ffSDmitry Chagin /* SI_USER, SI_KERNEL */ 7027ac9766dSDmitry Chagin return (EPERM); 7037ac9766dSDmitry Chagin 7044ab7403bSDmitry Chagin sig = linux_to_bsd_signal(args->sig); 7059c1045ffSDmitry Chagin ksiginfo_init(&ksi); 7069c1045ffSDmitry Chagin error = lsiginfo_to_siginfo(td, &linfo, &ksi.ksi_info, sig); 7079c1045ffSDmitry Chagin if (error != 0) 7089c1045ffSDmitry Chagin return (error); 7097ac9766dSDmitry Chagin 7107ac9766dSDmitry Chagin error = ESRCH; 711537d0fb1SMateusz Guzik if ((p = pfind_any(args->pid)) != NULL) { 7127ac9766dSDmitry Chagin error = p_cansignal(td, p, sig); 7137ac9766dSDmitry Chagin if (error != 0) { 7147ac9766dSDmitry Chagin PROC_UNLOCK(p); 7157ac9766dSDmitry Chagin return (error); 7167ac9766dSDmitry Chagin } 7177ac9766dSDmitry Chagin error = tdsendsignal(p, NULL, sig, &ksi); 7187ac9766dSDmitry Chagin PROC_UNLOCK(p); 7197ac9766dSDmitry Chagin } 7207ac9766dSDmitry Chagin 7217ac9766dSDmitry Chagin return (error); 7227ac9766dSDmitry Chagin } 723486a06bdSDmitry Chagin 724486a06bdSDmitry Chagin int 725486a06bdSDmitry Chagin linux_rt_tgsigqueueinfo(struct thread *td, struct linux_rt_tgsigqueueinfo_args *args) 726486a06bdSDmitry Chagin { 727486a06bdSDmitry Chagin l_siginfo_t linfo; 728486a06bdSDmitry Chagin struct thread *tds; 729486a06bdSDmitry Chagin ksiginfo_t ksi; 730486a06bdSDmitry Chagin int error; 731486a06bdSDmitry Chagin int sig; 732486a06bdSDmitry Chagin 733486a06bdSDmitry Chagin if (!LINUX_SIG_VALID(args->sig)) 734486a06bdSDmitry Chagin return (EINVAL); 735486a06bdSDmitry Chagin 736486a06bdSDmitry Chagin error = copyin(args->uinfo, &linfo, sizeof(linfo)); 737486a06bdSDmitry Chagin if (error != 0) 738486a06bdSDmitry Chagin return (error); 739486a06bdSDmitry Chagin 740486a06bdSDmitry Chagin if (linfo.lsi_code >= 0) 741486a06bdSDmitry Chagin return (EPERM); 742486a06bdSDmitry Chagin 7439c1045ffSDmitry 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); 7489c1045ffSDmitry Chagin 749486a06bdSDmitry Chagin tds = linux_tdfind(td, args->tid, args->tgid); 750486a06bdSDmitry Chagin if (tds == NULL) 751486a06bdSDmitry Chagin return (ESRCH); 752486a06bdSDmitry Chagin 753486a06bdSDmitry Chagin return (linux_do_tkill(td, tds, &ksi)); 754486a06bdSDmitry Chagin } 755