The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/linux/linux_signal.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause
    3  *
    4  * Copyright (c) 1994-1995 Søren Schmidt
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include "opt_ktrace.h"
   33 
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/ktr.h>
   37 #include <sys/lock.h>
   38 #include <sys/mutex.h>
   39 #include <sys/sx.h>
   40 #include <sys/proc.h>
   41 #include <sys/signalvar.h>
   42 #include <sys/syscallsubr.h>
   43 #include <sys/sysproto.h>
   44 #ifdef KTRACE
   45 #include <sys/ktrace.h>
   46 #endif
   47 
   48 #include <security/audit/audit.h>
   49 
   50 #include "opt_compat.h"
   51 
   52 #ifdef COMPAT_LINUX32
   53 #include <machine/../linux32/linux.h>
   54 #include <machine/../linux32/linux32_proto.h>
   55 #else
   56 #include <machine/../linux/linux.h>
   57 #include <machine/../linux/linux_proto.h>
   58 #endif
   59 #include <compat/linux/linux_mib.h>
   60 #include <compat/linux/linux_signal.h>
   61 #include <compat/linux/linux_timer.h>
   62 #include <compat/linux/linux_util.h>
   63 #include <compat/linux/linux_emul.h>
   64 #include <compat/linux/linux_misc.h>
   65 
   66 static int      linux_pksignal(struct thread *td, int pid, int sig,
   67                     ksiginfo_t *ksi);
   68 static int      linux_psignal(struct thread *td, int pid, int sig);
   69 static int      linux_tdksignal(struct thread *td, lwpid_t tid,
   70                     int tgid, int sig, ksiginfo_t *ksi);
   71 static int      linux_tdsignal(struct thread *td, lwpid_t tid,
   72                     int tgid, int sig);
   73 static void     sicode_to_lsicode(int sig, int si_code, int *lsi_code);
   74 static int      linux_common_rt_sigtimedwait(struct thread *,
   75                     l_sigset_t *, struct timespec *, l_siginfo_t *,
   76                     l_size_t);
   77 
   78 static void
   79 linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
   80 {
   81         unsigned long flags;
   82 
   83         linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask);
   84         bsa->sa_handler = PTRIN(lsa->lsa_handler);
   85         bsa->sa_flags = 0;
   86 
   87         flags = lsa->lsa_flags;
   88         if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) {
   89                 flags &= ~LINUX_SA_NOCLDSTOP;
   90                 bsa->sa_flags |= SA_NOCLDSTOP;
   91         }
   92         if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) {
   93                 flags &= ~LINUX_SA_NOCLDWAIT;
   94                 bsa->sa_flags |= SA_NOCLDWAIT;
   95         }
   96         if (lsa->lsa_flags & LINUX_SA_SIGINFO) {
   97                 flags &= ~LINUX_SA_SIGINFO;
   98                 bsa->sa_flags |= SA_SIGINFO;
   99 #ifdef notyet
  100                 /*
  101                  * XXX: We seem to be missing code to convert
  102                  *      some of the fields in ucontext_t.
  103                  */
  104                 linux_msg(curthread,
  105                     "partially unsupported sigaction flag SA_SIGINFO");
  106 #endif
  107         }
  108         if (lsa->lsa_flags & LINUX_SA_RESTORER) {
  109                 flags &= ~LINUX_SA_RESTORER;
  110                 /*
  111                  * We ignore the lsa_restorer and always use our own signal
  112                  * trampoline instead.  It looks like SA_RESTORER is obsolete
  113                  * in Linux too - it doesn't seem to be used at all on arm64.
  114                  * In any case: see Linux sigreturn(2).
  115                  */
  116         }
  117         if (lsa->lsa_flags & LINUX_SA_ONSTACK) {
  118                 flags &= ~LINUX_SA_ONSTACK;
  119                 bsa->sa_flags |= SA_ONSTACK;
  120         }
  121         if (lsa->lsa_flags & LINUX_SA_RESTART) {
  122                 flags &= ~LINUX_SA_RESTART;
  123                 bsa->sa_flags |= SA_RESTART;
  124         }
  125         if (lsa->lsa_flags & LINUX_SA_INTERRUPT) {
  126                 flags &= ~LINUX_SA_INTERRUPT;
  127                 /* Documented to be a "historical no-op". */
  128         }
  129         if (lsa->lsa_flags & LINUX_SA_ONESHOT) {
  130                 flags &= ~LINUX_SA_ONESHOT;
  131                 bsa->sa_flags |= SA_RESETHAND;
  132         }
  133         if (lsa->lsa_flags & LINUX_SA_NOMASK) {
  134                 flags &= ~LINUX_SA_NOMASK;
  135                 bsa->sa_flags |= SA_NODEFER;
  136         }
  137 
  138         if (flags != 0)
  139                 linux_msg(curthread, "unsupported sigaction flag %#lx", flags);
  140 }
  141 
  142 static void
  143 bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa)
  144 {
  145 
  146         bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask);
  147 #ifdef COMPAT_LINUX32
  148         lsa->lsa_handler = (uintptr_t)bsa->sa_handler;
  149 #else
  150         lsa->lsa_handler = bsa->sa_handler;
  151 #endif
  152         lsa->lsa_restorer = 0;          /* unsupported */
  153         lsa->lsa_flags = 0;
  154         if (bsa->sa_flags & SA_NOCLDSTOP)
  155                 lsa->lsa_flags |= LINUX_SA_NOCLDSTOP;
  156         if (bsa->sa_flags & SA_NOCLDWAIT)
  157                 lsa->lsa_flags |= LINUX_SA_NOCLDWAIT;
  158         if (bsa->sa_flags & SA_SIGINFO)
  159                 lsa->lsa_flags |= LINUX_SA_SIGINFO;
  160         if (bsa->sa_flags & SA_ONSTACK)
  161                 lsa->lsa_flags |= LINUX_SA_ONSTACK;
  162         if (bsa->sa_flags & SA_RESTART)
  163                 lsa->lsa_flags |= LINUX_SA_RESTART;
  164         if (bsa->sa_flags & SA_RESETHAND)
  165                 lsa->lsa_flags |= LINUX_SA_ONESHOT;
  166         if (bsa->sa_flags & SA_NODEFER)
  167                 lsa->lsa_flags |= LINUX_SA_NOMASK;
  168 }
  169 
  170 int
  171 linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa,
  172                    l_sigaction_t *linux_osa)
  173 {
  174         struct sigaction act, oact, *nsa, *osa;
  175         int error, sig;
  176 
  177         if (!LINUX_SIG_VALID(linux_sig))
  178                 return (EINVAL);
  179 
  180         osa = (linux_osa != NULL) ? &oact : NULL;
  181         if (linux_nsa != NULL) {
  182                 nsa = &act;
  183                 linux_to_bsd_sigaction(linux_nsa, nsa);
  184 #ifdef KTRACE
  185                 if (KTRPOINT(td, KTR_STRUCT))
  186                         linux_ktrsigset(&linux_nsa->lsa_mask,
  187                             sizeof(linux_nsa->lsa_mask));
  188 #endif
  189         } else
  190                 nsa = NULL;
  191         sig = linux_to_bsd_signal(linux_sig);
  192 
  193         error = kern_sigaction(td, sig, nsa, osa, 0);
  194         if (error != 0)
  195                 return (error);
  196 
  197         if (linux_osa != NULL) {
  198                 bsd_to_linux_sigaction(osa, linux_osa);
  199 #ifdef KTRACE
  200                 if (KTRPOINT(td, KTR_STRUCT))
  201                         linux_ktrsigset(&linux_osa->lsa_mask,
  202                             sizeof(linux_osa->lsa_mask));
  203 #endif
  204         }
  205         return (0);
  206 }
  207 
  208 int
  209 linux_sigaltstack(struct thread *td, struct linux_sigaltstack_args *uap)
  210 {
  211         stack_t ss, oss;
  212         l_stack_t lss;
  213         int error;
  214 
  215         memset(&lss, 0, sizeof(lss));
  216         LINUX_CTR2(sigaltstack, "%p, %p", uap->uss, uap->uoss);
  217 
  218         if (uap->uss != NULL) {
  219                 error = copyin(uap->uss, &lss, sizeof(lss));
  220                 if (error != 0)
  221                         return (error);
  222 
  223                 ss.ss_sp = PTRIN(lss.ss_sp);
  224                 ss.ss_size = lss.ss_size;
  225                 ss.ss_flags = linux_to_bsd_sigaltstack(lss.ss_flags);
  226         }
  227         error = kern_sigaltstack(td, (uap->uss != NULL) ? &ss : NULL,
  228             (uap->uoss != NULL) ? &oss : NULL);
  229         if (error == 0 && uap->uoss != NULL) {
  230                 lss.ss_sp = PTROUT(oss.ss_sp);
  231                 lss.ss_size = oss.ss_size;
  232                 lss.ss_flags = bsd_to_linux_sigaltstack(oss.ss_flags);
  233                 error = copyout(&lss, uap->uoss, sizeof(lss));
  234         }
  235 
  236         return (error);
  237 }
  238 
  239 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
  240 int
  241 linux_signal(struct thread *td, struct linux_signal_args *args)
  242 {
  243         l_sigaction_t nsa, osa;
  244         int error;
  245 
  246         nsa.lsa_handler = args->handler;
  247         nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK;
  248         LINUX_SIGEMPTYSET(nsa.lsa_mask);
  249 
  250         error = linux_do_sigaction(td, args->sig, &nsa, &osa);
  251         td->td_retval[0] = (int)(intptr_t)osa.lsa_handler;
  252 
  253         return (error);
  254 }
  255 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
  256 
  257 int
  258 linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args)
  259 {
  260         l_sigaction_t nsa, osa;
  261         int error;
  262 
  263         if (args->sigsetsize != sizeof(l_sigset_t))
  264                 return (EINVAL);
  265 
  266         if (args->act != NULL) {
  267                 error = copyin(args->act, &nsa, sizeof(nsa));
  268                 if (error != 0)
  269                         return (error);
  270         }
  271 
  272         error = linux_do_sigaction(td, args->sig,
  273                                    args->act ? &nsa : NULL,
  274                                    args->oact ? &osa : NULL);
  275 
  276         if (args->oact != NULL && error == 0)
  277                 error = copyout(&osa, args->oact, sizeof(osa));
  278 
  279         return (error);
  280 }
  281 
  282 static int
  283 linux_do_sigprocmask(struct thread *td, int how, sigset_t *new,
  284                      l_sigset_t *old)
  285 {
  286         sigset_t omask;
  287         int error;
  288 
  289         td->td_retval[0] = 0;
  290 
  291         switch (how) {
  292         case LINUX_SIG_BLOCK:
  293                 how = SIG_BLOCK;
  294                 break;
  295         case LINUX_SIG_UNBLOCK:
  296                 how = SIG_UNBLOCK;
  297                 break;
  298         case LINUX_SIG_SETMASK:
  299                 how = SIG_SETMASK;
  300                 break;
  301         default:
  302                 return (EINVAL);
  303         }
  304         error = kern_sigprocmask(td, how, new, &omask, 0);
  305         if (error == 0 && old != NULL)
  306                 bsd_to_linux_sigset(&omask, old);
  307 
  308         return (error);
  309 }
  310 
  311 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
  312 int
  313 linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args)
  314 {
  315         l_osigset_t mask;
  316         l_sigset_t lset, oset;
  317         sigset_t set;
  318         int error;
  319 
  320         if (args->mask != NULL) {
  321                 error = copyin(args->mask, &mask, sizeof(mask));
  322                 if (error != 0)
  323                         return (error);
  324                 LINUX_SIGEMPTYSET(lset);
  325                 lset.__mask = mask;
  326 #ifdef KTRACE
  327                 if (KTRPOINT(td, KTR_STRUCT))
  328                         linux_ktrsigset(&lset, sizeof(lset));
  329 #endif
  330                 linux_to_bsd_sigset(&lset, &set);
  331         }
  332 
  333         error = linux_do_sigprocmask(td, args->how,
  334                                      args->mask ? &set : NULL,
  335                                      args->omask ? &oset : NULL);
  336 
  337         if (args->omask != NULL && error == 0) {
  338 #ifdef KTRACE
  339                 if (KTRPOINT(td, KTR_STRUCT))
  340                         linux_ktrsigset(&oset, sizeof(oset));
  341 #endif
  342                 mask = oset.__mask;
  343                 error = copyout(&mask, args->omask, sizeof(mask));
  344         }
  345 
  346         return (error);
  347 }
  348 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
  349 
  350 int
  351 linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args)
  352 {
  353         l_sigset_t oset;
  354         sigset_t set, *pset;
  355         int error;
  356 
  357         error = linux_copyin_sigset(td, args->mask, args->sigsetsize,
  358             &set, &pset);
  359         if (error != 0)
  360                 return (EINVAL);
  361 
  362         error = linux_do_sigprocmask(td, args->how, pset,
  363                                      args->omask ? &oset : NULL);
  364 
  365         if (args->omask != NULL && error == 0) {
  366 #ifdef KTRACE
  367                 if (KTRPOINT(td, KTR_STRUCT))
  368                         linux_ktrsigset(&oset, sizeof(oset));
  369 #endif
  370                 error = copyout(&oset, args->omask, sizeof(oset));
  371         }
  372 
  373         return (error);
  374 }
  375 
  376 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
  377 int
  378 linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args)
  379 {
  380         struct proc *p = td->td_proc;
  381         l_sigset_t mask;
  382 
  383         PROC_LOCK(p);
  384         bsd_to_linux_sigset(&td->td_sigmask, &mask);
  385         PROC_UNLOCK(p);
  386         td->td_retval[0] = mask.__mask;
  387 #ifdef KTRACE
  388         if (KTRPOINT(td, KTR_STRUCT))
  389                 linux_ktrsigset(&mask, sizeof(mask));
  390 #endif
  391         return (0);
  392 }
  393 
  394 int
  395 linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args)
  396 {
  397         struct proc *p = td->td_proc;
  398         l_sigset_t lset;
  399         sigset_t bset;
  400 
  401         PROC_LOCK(p);
  402         bsd_to_linux_sigset(&td->td_sigmask, &lset);
  403         td->td_retval[0] = lset.__mask;
  404         LINUX_SIGEMPTYSET(lset);
  405         lset.__mask = args->mask;
  406         linux_to_bsd_sigset(&lset, &bset);
  407 #ifdef KTRACE
  408         if (KTRPOINT(td, KTR_STRUCT))
  409                 linux_ktrsigset(&lset, sizeof(lset));
  410 #endif
  411         td->td_sigmask = bset;
  412         SIG_CANTMASK(td->td_sigmask);
  413         signotify(td);
  414         PROC_UNLOCK(p);
  415         return (0);
  416 }
  417 
  418 int
  419 linux_sigpending(struct thread *td, struct linux_sigpending_args *args)
  420 {
  421         struct proc *p = td->td_proc;
  422         sigset_t bset;
  423         l_sigset_t lset;
  424         l_osigset_t mask;
  425 
  426         PROC_LOCK(p);
  427         bset = p->p_siglist;
  428         SIGSETOR(bset, td->td_siglist);
  429         SIGSETAND(bset, td->td_sigmask);
  430         PROC_UNLOCK(p);
  431         bsd_to_linux_sigset(&bset, &lset);
  432 #ifdef KTRACE
  433         if (KTRPOINT(td, KTR_STRUCT))
  434                 linux_ktrsigset(&lset, sizeof(lset));
  435 #endif
  436         mask = lset.__mask;
  437         return (copyout(&mask, args->mask, sizeof(mask)));
  438 }
  439 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
  440 
  441 /*
  442  * MPSAFE
  443  */
  444 int
  445 linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args)
  446 {
  447         struct proc *p = td->td_proc;
  448         sigset_t bset;
  449         l_sigset_t lset;
  450 
  451         if (args->sigsetsize > sizeof(lset))
  452                 return (EINVAL);
  453                 /* NOT REACHED */
  454 
  455         PROC_LOCK(p);
  456         bset = p->p_siglist;
  457         SIGSETOR(bset, td->td_siglist);
  458         SIGSETAND(bset, td->td_sigmask);
  459         PROC_UNLOCK(p);
  460         bsd_to_linux_sigset(&bset, &lset);
  461 #ifdef KTRACE
  462         if (KTRPOINT(td, KTR_STRUCT))
  463                 linux_ktrsigset(&lset, sizeof(lset));
  464 #endif
  465         return (copyout(&lset, args->set, args->sigsetsize));
  466 }
  467 
  468 int
  469 linux_rt_sigtimedwait(struct thread *td,
  470         struct linux_rt_sigtimedwait_args *args)
  471 {
  472         struct timespec ts, *tsa;
  473         int error;
  474 
  475         if (args->timeout) {
  476                 error = linux_get_timespec(&ts, args->timeout);
  477                 if (error != 0)
  478                         return (error);
  479                 tsa = &ts;
  480         } else
  481                 tsa = NULL;
  482 
  483         return (linux_common_rt_sigtimedwait(td, args->mask, tsa,
  484             args->ptr, args->sigsetsize));
  485 }
  486 
  487 static int
  488 linux_common_rt_sigtimedwait(struct thread *td, l_sigset_t *mask,
  489     struct timespec *tsa, l_siginfo_t *ptr, l_size_t sigsetsize)
  490 {
  491         int error, sig;
  492         sigset_t bset;
  493         l_siginfo_t lsi;
  494         ksiginfo_t ksi;
  495 
  496         error = linux_copyin_sigset(td, mask, sigsetsize, &bset, NULL);
  497         if (error != 0)
  498                 return (error);
  499 
  500         ksiginfo_init(&ksi);
  501         error = kern_sigtimedwait(td, bset, &ksi, tsa);
  502         if (error != 0)
  503                 return (error);
  504 
  505         sig = bsd_to_linux_signal(ksi.ksi_signo);
  506 
  507         if (ptr) {
  508                 memset(&lsi, 0, sizeof(lsi));
  509                 siginfo_to_lsiginfo(&ksi.ksi_info, &lsi, sig);
  510                 error = copyout(&lsi, ptr, sizeof(lsi));
  511         }
  512         if (error == 0)
  513                 td->td_retval[0] = sig;
  514 
  515         return (error);
  516 }
  517 
  518 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
  519 int
  520 linux_rt_sigtimedwait_time64(struct thread *td,
  521         struct linux_rt_sigtimedwait_time64_args *args)
  522 {
  523         struct timespec ts, *tsa;
  524         int error;
  525 
  526         if (args->timeout) {
  527                 error = linux_get_timespec64(&ts, args->timeout);
  528                 if (error != 0)
  529                         return (error);
  530                 tsa = &ts;
  531         } else
  532                 tsa = NULL;
  533 
  534         return (linux_common_rt_sigtimedwait(td, args->mask, tsa,
  535             args->ptr, args->sigsetsize));
  536 }
  537 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
  538 
  539 int
  540 linux_kill(struct thread *td, struct linux_kill_args *args)
  541 {
  542         int sig;
  543 
  544         /*
  545          * Allow signal 0 as a means to check for privileges
  546          */
  547         if (!LINUX_SIG_VALID(args->signum) && args->signum != 0)
  548                 return (EINVAL);
  549 
  550         if (args->signum > 0)
  551                 sig = linux_to_bsd_signal(args->signum);
  552         else
  553                 sig = 0;
  554 
  555         if (args->pid > PID_MAX)
  556                 return (linux_psignal(td, args->pid, sig));
  557         else
  558                 return (kern_kill(td, args->pid, sig));
  559 }
  560 
  561 int
  562 linux_tgkill(struct thread *td, struct linux_tgkill_args *args)
  563 {
  564         int sig;
  565 
  566         if (args->pid <= 0 || args->tgid <=0)
  567                 return (EINVAL);
  568 
  569         /*
  570          * Allow signal 0 as a means to check for privileges
  571          */
  572         if (!LINUX_SIG_VALID(args->sig) && args->sig != 0)
  573                 return (EINVAL);
  574 
  575         if (args->sig > 0)
  576                 sig = linux_to_bsd_signal(args->sig);
  577         else
  578                 sig = 0;
  579 
  580         return (linux_tdsignal(td, args->pid, args->tgid, sig));
  581 }
  582 
  583 /*
  584  * Deprecated since 2.5.75. Replaced by tgkill().
  585  */
  586 int
  587 linux_tkill(struct thread *td, struct linux_tkill_args *args)
  588 {
  589         int sig;
  590 
  591         if (args->tid <= 0)
  592                 return (EINVAL);
  593 
  594         if (!LINUX_SIG_VALID(args->sig))
  595                 return (EINVAL);
  596 
  597         sig = linux_to_bsd_signal(args->sig);
  598 
  599         return (linux_tdsignal(td, args->tid, -1, sig));
  600 }
  601 
  602 static int
  603 sigfpe_sicode2lsicode(int si_code)
  604 {
  605 
  606         switch (si_code) {
  607         case FPE_INTOVF:
  608                 return (LINUX_FPE_INTOVF);
  609         case FPE_INTDIV:
  610                 return (LINUX_FPE_INTDIV);
  611         case FPE_FLTIDO:
  612                 return (LINUX_FPE_FLTUNK);
  613         default:
  614                 return (si_code);
  615         }
  616 }
  617 
  618 static int
  619 sigbus_sicode2lsicode(int si_code)
  620 {
  621 
  622         switch (si_code) {
  623         case BUS_OOMERR:
  624                 return (LINUX_BUS_MCEERR_AR);
  625         default:
  626                 return (si_code);
  627         }
  628 }
  629 
  630 static int
  631 sigsegv_sicode2lsicode(int si_code)
  632 {
  633 
  634         switch (si_code) {
  635         case SEGV_PKUERR:
  636                 return (LINUX_SEGV_PKUERR);
  637         default:
  638                 return (si_code);
  639         }
  640 }
  641 
  642 static int
  643 sigtrap_sicode2lsicode(int si_code)
  644 {
  645 
  646         switch (si_code) {
  647         case TRAP_DTRACE:
  648                 return (LINUX_TRAP_TRACE);
  649         case TRAP_CAP:
  650                 return (LINUX_TRAP_UNK);
  651         default:
  652                 return (si_code);
  653         }
  654 }
  655 
  656 static void
  657 sicode_to_lsicode(int sig, int si_code, int *lsi_code)
  658 {
  659 
  660         switch (si_code) {
  661         case SI_USER:
  662                 *lsi_code = LINUX_SI_USER;
  663                 break;
  664         case SI_KERNEL:
  665                 *lsi_code = LINUX_SI_KERNEL;
  666                 break;
  667         case SI_QUEUE:
  668                 *lsi_code = LINUX_SI_QUEUE;
  669                 break;
  670         case SI_TIMER:
  671                 *lsi_code = LINUX_SI_TIMER;
  672                 break;
  673         case SI_MESGQ:
  674                 *lsi_code = LINUX_SI_MESGQ;
  675                 break;
  676         case SI_ASYNCIO:
  677                 *lsi_code = LINUX_SI_ASYNCIO;
  678                 break;
  679         case SI_LWP:
  680                 *lsi_code = LINUX_SI_TKILL;
  681                 break;
  682         default:
  683                 switch (sig) {
  684                 case LINUX_SIGFPE:
  685                         *lsi_code = sigfpe_sicode2lsicode(si_code);
  686                         break;
  687                 case LINUX_SIGBUS:
  688                         *lsi_code = sigbus_sicode2lsicode(si_code);
  689                         break;
  690                 case LINUX_SIGSEGV:
  691                         *lsi_code = sigsegv_sicode2lsicode(si_code);
  692                         break;
  693                 case LINUX_SIGTRAP:
  694                         *lsi_code = sigtrap_sicode2lsicode(si_code);
  695                         break;
  696                 default:
  697                         *lsi_code = si_code;
  698                         break;
  699                 }
  700                 break;
  701         }
  702 }
  703 
  704 void
  705 siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig)
  706 {
  707 
  708         /* sig already converted */
  709         lsi->lsi_signo = sig;
  710         sicode_to_lsicode(sig, si->si_code, &lsi->lsi_code);
  711 
  712         switch (si->si_code) {
  713         case SI_LWP:
  714                 lsi->lsi_pid = si->si_pid;
  715                 lsi->lsi_uid = si->si_uid;
  716                 break;
  717 
  718         case SI_TIMER:
  719                 lsi->lsi_int = si->si_value.sival_int;
  720                 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr);
  721                 lsi->lsi_tid = si->si_timerid;
  722                 break;
  723 
  724         case SI_QUEUE:
  725                 lsi->lsi_pid = si->si_pid;
  726                 lsi->lsi_uid = si->si_uid;
  727                 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr);
  728                 break;
  729 
  730         case SI_ASYNCIO:
  731                 lsi->lsi_int = si->si_value.sival_int;
  732                 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr);
  733                 break;
  734 
  735         default:
  736                 switch (sig) {
  737                 case LINUX_SIGPOLL:
  738                         /* XXX si_fd? */
  739                         lsi->lsi_band = si->si_band;
  740                         break;
  741 
  742                 case LINUX_SIGCHLD:
  743                         lsi->lsi_errno = 0;
  744                         lsi->lsi_pid = si->si_pid;
  745                         lsi->lsi_uid = si->si_uid;
  746 
  747                         if (si->si_code == CLD_STOPPED || si->si_code == CLD_KILLED)
  748                                 lsi->lsi_status = bsd_to_linux_signal(si->si_status);
  749                         else if (si->si_code == CLD_CONTINUED)
  750                                 lsi->lsi_status = bsd_to_linux_signal(SIGCONT);
  751                         else
  752                                 lsi->lsi_status = si->si_status;
  753                         break;
  754 
  755                 case LINUX_SIGBUS:
  756                 case LINUX_SIGILL:
  757                 case LINUX_SIGFPE:
  758                 case LINUX_SIGSEGV:
  759                         lsi->lsi_addr = PTROUT(si->si_addr);
  760                         break;
  761 
  762                 default:
  763                         lsi->lsi_pid = si->si_pid;
  764                         lsi->lsi_uid = si->si_uid;
  765                         if (sig >= LINUX_SIGRTMIN) {
  766                                 lsi->lsi_int = si->si_value.sival_int;
  767                                 lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr);
  768                         }
  769                         break;
  770                 }
  771                 break;
  772         }
  773 }
  774 
  775 int
  776 lsiginfo_to_siginfo(struct thread *td, const l_siginfo_t *lsi,
  777     siginfo_t *si, int sig)
  778 {
  779 
  780         switch (lsi->lsi_code) {
  781         case LINUX_SI_TKILL:
  782                 if (linux_kernver(td) >= LINUX_KERNVER_2006039) {
  783                         linux_msg(td, "SI_TKILL forbidden since 2.6.39");
  784                         return (EPERM);
  785                 }
  786                 si->si_code = SI_LWP;
  787         case LINUX_SI_QUEUE:
  788                 si->si_code = SI_QUEUE;
  789                 break;
  790         case LINUX_SI_TIMER:
  791                 si->si_code = SI_TIMER;
  792                 break;
  793         case LINUX_SI_MESGQ:
  794                 si->si_code = SI_MESGQ;
  795                 break;
  796         case LINUX_SI_ASYNCIO:
  797                 si->si_code = SI_ASYNCIO;
  798                 break;
  799         default:
  800                 si->si_code = lsi->lsi_code;
  801                 break;
  802         }
  803 
  804         si->si_signo = sig;
  805         si->si_pid = td->td_proc->p_pid;
  806         si->si_uid = td->td_ucred->cr_ruid;
  807         si->si_value.sival_ptr = PTRIN(lsi->lsi_value.sival_ptr);
  808         return (0);
  809 }
  810 
  811 int
  812 linux_rt_sigqueueinfo(struct thread *td, struct linux_rt_sigqueueinfo_args *args)
  813 {
  814         l_siginfo_t linfo;
  815         ksiginfo_t ksi;
  816         int error;
  817         int sig;
  818 
  819         if (!LINUX_SIG_VALID(args->sig))
  820                 return (EINVAL);
  821 
  822         error = copyin(args->info, &linfo, sizeof(linfo));
  823         if (error != 0)
  824                 return (error);
  825 
  826         if (linfo.lsi_code >= 0)
  827                 /* SI_USER, SI_KERNEL */
  828                 return (EPERM);
  829 
  830         sig = linux_to_bsd_signal(args->sig);
  831         ksiginfo_init(&ksi);
  832         error = lsiginfo_to_siginfo(td, &linfo, &ksi.ksi_info, sig);
  833         if (error != 0)
  834                 return (error);
  835 
  836         return (linux_pksignal(td, args->pid, sig, &ksi));
  837 }
  838 
  839 int
  840 linux_rt_tgsigqueueinfo(struct thread *td, struct linux_rt_tgsigqueueinfo_args *args)
  841 {
  842         l_siginfo_t linfo;
  843         ksiginfo_t ksi;
  844         int error;
  845         int sig;
  846 
  847         if (!LINUX_SIG_VALID(args->sig))
  848                 return (EINVAL);
  849 
  850         error = copyin(args->uinfo, &linfo, sizeof(linfo));
  851         if (error != 0)
  852                 return (error);
  853 
  854         if (linfo.lsi_code >= 0)
  855                 return (EPERM);
  856 
  857         sig = linux_to_bsd_signal(args->sig);
  858         ksiginfo_init(&ksi);
  859         error = lsiginfo_to_siginfo(td, &linfo, &ksi.ksi_info, sig);
  860         if (error != 0)
  861                 return (error);
  862 
  863         return (linux_tdksignal(td, args->tid, args->tgid, sig, &ksi));
  864 }
  865 
  866 int
  867 linux_rt_sigsuspend(struct thread *td, struct linux_rt_sigsuspend_args *uap)
  868 {
  869         sigset_t sigmask;
  870         int error;
  871 
  872         error = linux_copyin_sigset(td, uap->newset, uap->sigsetsize,
  873             &sigmask, NULL);
  874         if (error != 0)
  875                 return (error);
  876 
  877         return (kern_sigsuspend(td, sigmask));
  878 }
  879 
  880 static int
  881 linux_tdksignal(struct thread *td, lwpid_t tid, int tgid, int sig,
  882     ksiginfo_t *ksi)
  883 {
  884         struct thread *tdt;
  885         struct proc *p;
  886         int error;
  887 
  888         tdt = linux_tdfind(td, tid, tgid);
  889         if (tdt == NULL)
  890                 return (ESRCH);
  891 
  892         p = tdt->td_proc;
  893         AUDIT_ARG_SIGNUM(sig);
  894         AUDIT_ARG_PID(p->p_pid);
  895         AUDIT_ARG_PROCESS(p);
  896 
  897         error = p_cansignal(td, p, sig);
  898         if (error != 0 || sig == 0)
  899                 goto out;
  900 
  901         tdksignal(tdt, sig, ksi);
  902 
  903 out:
  904         PROC_UNLOCK(p);
  905         return (error);
  906 }
  907 
  908 static int
  909 linux_tdsignal(struct thread *td, lwpid_t tid, int tgid, int sig)
  910 {
  911         ksiginfo_t ksi;
  912 
  913         ksiginfo_init(&ksi);
  914         ksi.ksi_signo = sig;
  915         ksi.ksi_code = SI_LWP;
  916         ksi.ksi_pid = td->td_proc->p_pid;
  917         ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid;
  918         return (linux_tdksignal(td, tid, tgid, sig, &ksi));
  919 }
  920 
  921 static int
  922 linux_pksignal(struct thread *td, int pid, int sig, ksiginfo_t *ksi)
  923 {
  924         struct thread *tdt;
  925         struct proc *p;
  926         int error;
  927 
  928         tdt = linux_tdfind(td, pid, -1);
  929         if (tdt == NULL)
  930                 return (ESRCH);
  931 
  932         p = tdt->td_proc;
  933         AUDIT_ARG_SIGNUM(sig);
  934         AUDIT_ARG_PID(p->p_pid);
  935         AUDIT_ARG_PROCESS(p);
  936 
  937         error = p_cansignal(td, p, sig);
  938         if (error != 0 || sig == 0)
  939                 goto out;
  940 
  941         pksignal(p, sig, ksi);
  942 
  943 out:
  944         PROC_UNLOCK(p);
  945         return (error);
  946 }
  947 
  948 static int
  949 linux_psignal(struct thread *td, int pid, int sig)
  950 {
  951         ksiginfo_t ksi;
  952 
  953         ksiginfo_init(&ksi);
  954         ksi.ksi_signo = sig;
  955         ksi.ksi_code = SI_LWP;
  956         ksi.ksi_pid = td->td_proc->p_pid;
  957         ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid;
  958         return (linux_pksignal(td, pid, sig, &ksi));
  959 }
  960 
  961 int
  962 linux_copyin_sigset(struct thread *td, l_sigset_t *lset,
  963     l_size_t sigsetsize, sigset_t *set, sigset_t **pset)
  964 {
  965         l_sigset_t lmask;
  966         int error;
  967 
  968         if (sigsetsize != sizeof(l_sigset_t))
  969                 return (EINVAL);
  970         if (lset != NULL) {
  971                 error = copyin(lset, &lmask, sizeof(lmask));
  972                 if (error != 0)
  973                         return (error);
  974                 linux_to_bsd_sigset(&lmask, set);
  975                 if (pset != NULL)
  976                         *pset = set;
  977 #ifdef KTRACE
  978                 if (KTRPOINT(td, KTR_STRUCT))
  979                         linux_ktrsigset(&lmask, sizeof(lmask));
  980 #endif
  981         } else if (pset != NULL)
  982                 *pset = NULL;
  983         return (0);
  984 }

Cache object: 7e1de20b2d82a84e52814fe30374fb50


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.