xref: /freebsd/sys/compat/linux/linux_signal.c (revision 3e8eb5c7f4909209c042403ddee340b2ee7003a5)
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 alredy 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 }
985