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