xref: /freebsd-src/sys/compat/linux/linux_signal.c (revision 1603881667360c015f6685131f2f25474fa67a72)
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 <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/lock.h>
35 #include <sys/mutex.h>
36 #include <sys/sx.h>
37 #include <sys/proc.h>
38 #include <sys/signalvar.h>
39 #include <sys/syscallsubr.h>
40 #include <sys/sysproto.h>
41 
42 #include <security/audit/audit.h>
43 
44 #include "opt_compat.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_timer.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_do_tkill(struct thread *td, struct thread *tdt,
61 		    ksiginfo_t *ksi);
62 static void	sicode_to_lsicode(int si_code, int *lsi_code);
63 
64 static void
65 linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
66 {
67 	unsigned long flags;
68 
69 	linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask);
70 	bsa->sa_handler = PTRIN(lsa->lsa_handler);
71 	bsa->sa_flags = 0;
72 
73 	flags = lsa->lsa_flags;
74 	if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP) {
75 		flags &= ~LINUX_SA_NOCLDSTOP;
76 		bsa->sa_flags |= SA_NOCLDSTOP;
77 	}
78 	if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT) {
79 		flags &= ~LINUX_SA_NOCLDWAIT;
80 		bsa->sa_flags |= SA_NOCLDWAIT;
81 	}
82 	if (lsa->lsa_flags & LINUX_SA_SIGINFO) {
83 		flags &= ~LINUX_SA_SIGINFO;
84 		bsa->sa_flags |= SA_SIGINFO;
85 #ifdef notyet
86 		/*
87 		 * XXX: We seem to be missing code to convert
88 		 *      some of the fields in ucontext_t.
89 		 */
90 		linux_msg(curthread,
91 		    "partially unsupported sigaction flag SA_SIGINFO");
92 #endif
93 	}
94 	if (lsa->lsa_flags & LINUX_SA_RESTORER) {
95 		flags &= ~LINUX_SA_RESTORER;
96 		/* XXX: We might want to handle it; see Linux sigreturn(2). */
97 	}
98 	if (lsa->lsa_flags & LINUX_SA_ONSTACK) {
99 		flags &= ~LINUX_SA_ONSTACK;
100 		bsa->sa_flags |= SA_ONSTACK;
101 	}
102 	if (lsa->lsa_flags & LINUX_SA_RESTART) {
103 		flags &= ~LINUX_SA_RESTART;
104 		bsa->sa_flags |= SA_RESTART;
105 	}
106 	if (lsa->lsa_flags & LINUX_SA_INTERRUPT) {
107 		flags &= ~LINUX_SA_INTERRUPT;
108 		/* Documented to be a "historical no-op". */
109 	}
110 	if (lsa->lsa_flags & LINUX_SA_ONESHOT) {
111 		flags &= ~LINUX_SA_ONESHOT;
112 		bsa->sa_flags |= SA_RESETHAND;
113 	}
114 	if (lsa->lsa_flags & LINUX_SA_NOMASK) {
115 		flags &= ~LINUX_SA_NOMASK;
116 		bsa->sa_flags |= SA_NODEFER;
117 	}
118 
119 	if (flags != 0)
120 		linux_msg(curthread, "unsupported sigaction flag %#lx", flags);
121 }
122 
123 static void
124 bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa)
125 {
126 
127 	bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask);
128 #ifdef COMPAT_LINUX32
129 	lsa->lsa_handler = (uintptr_t)bsa->sa_handler;
130 #else
131 	lsa->lsa_handler = bsa->sa_handler;
132 #endif
133 	lsa->lsa_restorer = 0;		/* unsupported */
134 	lsa->lsa_flags = 0;
135 	if (bsa->sa_flags & SA_NOCLDSTOP)
136 		lsa->lsa_flags |= LINUX_SA_NOCLDSTOP;
137 	if (bsa->sa_flags & SA_NOCLDWAIT)
138 		lsa->lsa_flags |= LINUX_SA_NOCLDWAIT;
139 	if (bsa->sa_flags & SA_SIGINFO)
140 		lsa->lsa_flags |= LINUX_SA_SIGINFO;
141 	if (bsa->sa_flags & SA_ONSTACK)
142 		lsa->lsa_flags |= LINUX_SA_ONSTACK;
143 	if (bsa->sa_flags & SA_RESTART)
144 		lsa->lsa_flags |= LINUX_SA_RESTART;
145 	if (bsa->sa_flags & SA_RESETHAND)
146 		lsa->lsa_flags |= LINUX_SA_ONESHOT;
147 	if (bsa->sa_flags & SA_NODEFER)
148 		lsa->lsa_flags |= LINUX_SA_NOMASK;
149 }
150 
151 int
152 linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa,
153 		   l_sigaction_t *linux_osa)
154 {
155 	struct sigaction act, oact, *nsa, *osa;
156 	int error, sig;
157 
158 	if (!LINUX_SIG_VALID(linux_sig))
159 		return (EINVAL);
160 
161 	osa = (linux_osa != NULL) ? &oact : NULL;
162 	if (linux_nsa != NULL) {
163 		nsa = &act;
164 		linux_to_bsd_sigaction(linux_nsa, nsa);
165 	} else
166 		nsa = NULL;
167 	sig = linux_to_bsd_signal(linux_sig);
168 
169 	error = kern_sigaction(td, sig, nsa, osa, 0);
170 	if (error)
171 		return (error);
172 
173 	if (linux_osa != NULL)
174 		bsd_to_linux_sigaction(osa, linux_osa);
175 
176 	return (0);
177 }
178 
179 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
180 int
181 linux_signal(struct thread *td, struct linux_signal_args *args)
182 {
183 	l_sigaction_t nsa, osa;
184 	int error;
185 
186 	nsa.lsa_handler = args->handler;
187 	nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK;
188 	LINUX_SIGEMPTYSET(nsa.lsa_mask);
189 
190 	error = linux_do_sigaction(td, args->sig, &nsa, &osa);
191 	td->td_retval[0] = (int)(intptr_t)osa.lsa_handler;
192 
193 	return (error);
194 }
195 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
196 
197 int
198 linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args)
199 {
200 	l_sigaction_t nsa, osa;
201 	int error;
202 
203 	if (args->sigsetsize != sizeof(l_sigset_t))
204 		return (EINVAL);
205 
206 	if (args->act != NULL) {
207 		error = copyin(args->act, &nsa, sizeof(l_sigaction_t));
208 		if (error)
209 			return (error);
210 	}
211 
212 	error = linux_do_sigaction(td, args->sig,
213 				   args->act ? &nsa : NULL,
214 				   args->oact ? &osa : NULL);
215 
216 	if (args->oact != NULL && !error) {
217 		error = copyout(&osa, args->oact, sizeof(l_sigaction_t));
218 	}
219 
220 	return (error);
221 }
222 
223 static int
224 linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new,
225 		     l_sigset_t *old)
226 {
227 	sigset_t omask, nmask;
228 	sigset_t *nmaskp;
229 	int error;
230 
231 	td->td_retval[0] = 0;
232 
233 	switch (how) {
234 	case LINUX_SIG_BLOCK:
235 		how = SIG_BLOCK;
236 		break;
237 	case LINUX_SIG_UNBLOCK:
238 		how = SIG_UNBLOCK;
239 		break;
240 	case LINUX_SIG_SETMASK:
241 		how = SIG_SETMASK;
242 		break;
243 	default:
244 		return (EINVAL);
245 	}
246 	if (new != NULL) {
247 		linux_to_bsd_sigset(new, &nmask);
248 		nmaskp = &nmask;
249 	} else
250 		nmaskp = NULL;
251 	error = kern_sigprocmask(td, how, nmaskp, &omask, 0);
252 	if (error == 0 && old != NULL)
253 		bsd_to_linux_sigset(&omask, old);
254 
255 	return (error);
256 }
257 
258 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
259 int
260 linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args)
261 {
262 	l_osigset_t mask;
263 	l_sigset_t set, oset;
264 	int error;
265 
266 	if (args->mask != NULL) {
267 		error = copyin(args->mask, &mask, sizeof(l_osigset_t));
268 		if (error)
269 			return (error);
270 		LINUX_SIGEMPTYSET(set);
271 		set.__mask = mask;
272 	}
273 
274 	error = linux_do_sigprocmask(td, args->how,
275 				     args->mask ? &set : NULL,
276 				     args->omask ? &oset : NULL);
277 
278 	if (args->omask != NULL && !error) {
279 		mask = oset.__mask;
280 		error = copyout(&mask, args->omask, sizeof(l_osigset_t));
281 	}
282 
283 	return (error);
284 }
285 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
286 
287 int
288 linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args)
289 {
290 	l_sigset_t set, oset;
291 	int error;
292 
293 	if (args->sigsetsize != sizeof(l_sigset_t))
294 		return (EINVAL);
295 
296 	if (args->mask != NULL) {
297 		error = copyin(args->mask, &set, sizeof(l_sigset_t));
298 		if (error)
299 			return (error);
300 	}
301 
302 	error = linux_do_sigprocmask(td, args->how,
303 				     args->mask ? &set : NULL,
304 				     args->omask ? &oset : NULL);
305 
306 	if (args->omask != NULL && !error) {
307 		error = copyout(&oset, args->omask, sizeof(l_sigset_t));
308 	}
309 
310 	return (error);
311 }
312 
313 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
314 int
315 linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args)
316 {
317 	struct proc *p = td->td_proc;
318 	l_sigset_t mask;
319 
320 	PROC_LOCK(p);
321 	bsd_to_linux_sigset(&td->td_sigmask, &mask);
322 	PROC_UNLOCK(p);
323 	td->td_retval[0] = mask.__mask;
324 	return (0);
325 }
326 
327 int
328 linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args)
329 {
330 	struct proc *p = td->td_proc;
331 	l_sigset_t lset;
332 	sigset_t bset;
333 
334 	PROC_LOCK(p);
335 	bsd_to_linux_sigset(&td->td_sigmask, &lset);
336 	td->td_retval[0] = lset.__mask;
337 	LINUX_SIGEMPTYSET(lset);
338 	lset.__mask = args->mask;
339 	linux_to_bsd_sigset(&lset, &bset);
340 	td->td_sigmask = bset;
341 	SIG_CANTMASK(td->td_sigmask);
342 	signotify(td);
343 	PROC_UNLOCK(p);
344 	return (0);
345 }
346 
347 int
348 linux_sigpending(struct thread *td, struct linux_sigpending_args *args)
349 {
350 	struct proc *p = td->td_proc;
351 	sigset_t bset;
352 	l_sigset_t lset;
353 	l_osigset_t mask;
354 
355 	PROC_LOCK(p);
356 	bset = p->p_siglist;
357 	SIGSETOR(bset, td->td_siglist);
358 	SIGSETAND(bset, td->td_sigmask);
359 	PROC_UNLOCK(p);
360 	bsd_to_linux_sigset(&bset, &lset);
361 	mask = lset.__mask;
362 	return (copyout(&mask, args->mask, sizeof(mask)));
363 }
364 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
365 
366 /*
367  * MPSAFE
368  */
369 int
370 linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args)
371 {
372 	struct proc *p = td->td_proc;
373 	sigset_t bset;
374 	l_sigset_t lset;
375 
376 	if (args->sigsetsize > sizeof(lset))
377 		return (EINVAL);
378 		/* NOT REACHED */
379 
380 	PROC_LOCK(p);
381 	bset = p->p_siglist;
382 	SIGSETOR(bset, td->td_siglist);
383 	SIGSETAND(bset, td->td_sigmask);
384 	PROC_UNLOCK(p);
385 	bsd_to_linux_sigset(&bset, &lset);
386 	return (copyout(&lset, args->set, args->sigsetsize));
387 }
388 
389 /*
390  * MPSAFE
391  */
392 int
393 linux_rt_sigtimedwait(struct thread *td,
394 	struct linux_rt_sigtimedwait_args *args)
395 {
396 	int error, sig;
397 	struct timespec ts, *tsa;
398 	struct l_timespec lts;
399 	l_sigset_t lset;
400 	sigset_t bset;
401 	l_siginfo_t lsi;
402 	ksiginfo_t ksi;
403 
404 	if (args->sigsetsize != sizeof(l_sigset_t))
405 		return (EINVAL);
406 
407 	if ((error = copyin(args->mask, &lset, sizeof(lset))))
408 		return (error);
409 	linux_to_bsd_sigset(&lset, &bset);
410 
411 	tsa = NULL;
412 	if (args->timeout) {
413 		if ((error = copyin(args->timeout, &lts, sizeof(lts))))
414 			return (error);
415 		error = linux_to_native_timespec(&ts, &lts);
416 		if (error != 0)
417 			return (error);
418 		tsa = &ts;
419 	} else
420 		tsa = NULL;
421 
422 	error = kern_sigtimedwait(td, bset, &ksi, tsa);
423 	if (error)
424 		return (error);
425 
426 	sig = bsd_to_linux_signal(ksi.ksi_signo);
427 
428 	if (args->ptr) {
429 		memset(&lsi, 0, sizeof(lsi));
430 		siginfo_to_lsiginfo(&ksi.ksi_info, &lsi, sig);
431 		error = copyout(&lsi, args->ptr, sizeof(lsi));
432 	}
433 	if (error == 0)
434 		td->td_retval[0] = sig;
435 
436 	return (error);
437 }
438 
439 int
440 linux_kill(struct thread *td, struct linux_kill_args *args)
441 {
442 	int l_signum;
443 
444 	/*
445 	 * Allow signal 0 as a means to check for privileges
446 	 */
447 	if (!LINUX_SIG_VALID(args->signum) && args->signum != 0)
448 		return (EINVAL);
449 
450 	if (args->signum > 0)
451 		l_signum = linux_to_bsd_signal(args->signum);
452 	else
453 		l_signum = 0;
454 
455 	return (kern_kill(td, args->pid, l_signum));
456 }
457 
458 static int
459 linux_do_tkill(struct thread *td, struct thread *tdt, ksiginfo_t *ksi)
460 {
461 	struct proc *p;
462 	int error;
463 
464 	p = tdt->td_proc;
465 	AUDIT_ARG_SIGNUM(ksi->ksi_signo);
466 	AUDIT_ARG_PID(p->p_pid);
467 	AUDIT_ARG_PROCESS(p);
468 
469 	error = p_cansignal(td, p, ksi->ksi_signo);
470 	if (error != 0 || ksi->ksi_signo == 0)
471 		goto out;
472 
473 	tdksignal(tdt, ksi->ksi_signo, ksi);
474 
475 out:
476 	PROC_UNLOCK(p);
477 	return (error);
478 }
479 
480 int
481 linux_tgkill(struct thread *td, struct linux_tgkill_args *args)
482 {
483 	struct thread *tdt;
484 	ksiginfo_t ksi;
485 	int sig;
486 
487 	if (args->pid <= 0 || args->tgid <=0)
488 		return (EINVAL);
489 
490 	/*
491 	 * Allow signal 0 as a means to check for privileges
492 	 */
493 	if (!LINUX_SIG_VALID(args->sig) && args->sig != 0)
494 		return (EINVAL);
495 
496 	if (args->sig > 0)
497 		sig = linux_to_bsd_signal(args->sig);
498 	else
499 		sig = 0;
500 
501 	tdt = linux_tdfind(td, args->pid, args->tgid);
502 	if (tdt == NULL)
503 		return (ESRCH);
504 
505 	ksiginfo_init(&ksi);
506 	ksi.ksi_signo = sig;
507 	ksi.ksi_code = SI_LWP;
508 	ksi.ksi_errno = 0;
509 	ksi.ksi_pid = td->td_proc->p_pid;
510 	ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid;
511 	return (linux_do_tkill(td, tdt, &ksi));
512 }
513 
514 /*
515  * Deprecated since 2.5.75. Replaced by tgkill().
516  */
517 int
518 linux_tkill(struct thread *td, struct linux_tkill_args *args)
519 {
520 	struct thread *tdt;
521 	ksiginfo_t ksi;
522 	int sig;
523 
524 	if (args->tid <= 0)
525 		return (EINVAL);
526 
527 	if (!LINUX_SIG_VALID(args->sig))
528 		return (EINVAL);
529 
530 	sig = linux_to_bsd_signal(args->sig);
531 
532 	tdt = linux_tdfind(td, args->tid, -1);
533 	if (tdt == NULL)
534 		return (ESRCH);
535 
536 	ksiginfo_init(&ksi);
537 	ksi.ksi_signo = sig;
538 	ksi.ksi_code = SI_LWP;
539 	ksi.ksi_errno = 0;
540 	ksi.ksi_pid = td->td_proc->p_pid;
541 	ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid;
542 	return (linux_do_tkill(td, tdt, &ksi));
543 }
544 
545 static void
546 sicode_to_lsicode(int si_code, int *lsi_code)
547 {
548 
549 	switch (si_code) {
550 	case SI_USER:
551 		*lsi_code = LINUX_SI_USER;
552 		break;
553 	case SI_KERNEL:
554 		*lsi_code = LINUX_SI_KERNEL;
555 		break;
556 	case SI_QUEUE:
557 		*lsi_code = LINUX_SI_QUEUE;
558 		break;
559 	case SI_TIMER:
560 		*lsi_code = LINUX_SI_TIMER;
561 		break;
562 	case SI_MESGQ:
563 		*lsi_code = LINUX_SI_MESGQ;
564 		break;
565 	case SI_ASYNCIO:
566 		*lsi_code = LINUX_SI_ASYNCIO;
567 		break;
568 	case SI_LWP:
569 		*lsi_code = LINUX_SI_TKILL;
570 		break;
571 	default:
572 		*lsi_code = si_code;
573 		break;
574 	}
575 }
576 
577 void
578 siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig)
579 {
580 
581 	/* sig alredy converted */
582 	lsi->lsi_signo = sig;
583 	sicode_to_lsicode(si->si_code, &lsi->lsi_code);
584 
585 	switch (si->si_code) {
586 	case SI_LWP:
587 		lsi->lsi_pid = si->si_pid;
588 		lsi->lsi_uid = si->si_uid;
589 		break;
590 
591 	case SI_TIMER:
592 		lsi->lsi_int = si->si_value.sival_int;
593 		lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr);
594 		lsi->lsi_tid = si->si_timerid;
595 		break;
596 
597 	case SI_QUEUE:
598 		lsi->lsi_pid = si->si_pid;
599 		lsi->lsi_uid = si->si_uid;
600 		lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr);
601 		break;
602 
603 	case SI_ASYNCIO:
604 		lsi->lsi_int = si->si_value.sival_int;
605 		lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr);
606 		break;
607 
608 	default:
609 		switch (sig) {
610 		case LINUX_SIGPOLL:
611 			/* XXX si_fd? */
612 			lsi->lsi_band = si->si_band;
613 			break;
614 
615 		case LINUX_SIGCHLD:
616 			lsi->lsi_errno = 0;
617 			lsi->lsi_pid = si->si_pid;
618 			lsi->lsi_uid = si->si_uid;
619 
620 			if (si->si_code == CLD_STOPPED)
621 				lsi->lsi_status = bsd_to_linux_signal(si->si_status);
622 			else if (si->si_code == CLD_CONTINUED)
623 				lsi->lsi_status = bsd_to_linux_signal(SIGCONT);
624 			else
625 				lsi->lsi_status = si->si_status;
626 			break;
627 
628 		case LINUX_SIGBUS:
629 		case LINUX_SIGILL:
630 		case LINUX_SIGFPE:
631 		case LINUX_SIGSEGV:
632 			lsi->lsi_addr = PTROUT(si->si_addr);
633 			break;
634 
635 		default:
636 			lsi->lsi_pid = si->si_pid;
637 			lsi->lsi_uid = si->si_uid;
638 			if (sig >= LINUX_SIGRTMIN) {
639 				lsi->lsi_int = si->si_value.sival_int;
640 				lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr);
641 			}
642 			break;
643 		}
644 		break;
645 	}
646 }
647 
648 int
649 lsiginfo_to_siginfo(struct thread *td, const l_siginfo_t *lsi,
650     siginfo_t *si, int sig)
651 {
652 
653 	switch (lsi->lsi_code) {
654 	case LINUX_SI_TKILL:
655 		if (linux_kernver(td) >= LINUX_KERNVER_2006039) {
656 			linux_msg(td, "SI_TKILL forbidden since 2.6.39");
657 			return (EPERM);
658 		}
659 		si->si_code = SI_LWP;
660 	case LINUX_SI_QUEUE:
661 		si->si_code = SI_QUEUE;
662 		break;
663 	case LINUX_SI_TIMER:
664 		si->si_code = SI_TIMER;
665 		break;
666 	case LINUX_SI_MESGQ:
667 		si->si_code = SI_MESGQ;
668 		break;
669 	case LINUX_SI_ASYNCIO:
670 		si->si_code = SI_ASYNCIO;
671 		break;
672 	default:
673 		si->si_code = lsi->lsi_code;
674 		break;
675 	}
676 
677 	si->si_signo = sig;
678 	si->si_pid = td->td_proc->p_pid;
679 	si->si_uid = td->td_ucred->cr_ruid;
680 	si->si_value.sival_ptr = PTRIN(lsi->lsi_value.sival_ptr);
681 	return (0);
682 }
683 
684 int
685 linux_rt_sigqueueinfo(struct thread *td, struct linux_rt_sigqueueinfo_args *args)
686 {
687 	l_siginfo_t linfo;
688 	struct proc *p;
689 	ksiginfo_t ksi;
690 	int error;
691 	int sig;
692 
693 	if (!LINUX_SIG_VALID(args->sig))
694 		return (EINVAL);
695 
696 	error = copyin(args->info, &linfo, sizeof(linfo));
697 	if (error != 0)
698 		return (error);
699 
700 	if (linfo.lsi_code >= 0)
701 		/* SI_USER, SI_KERNEL */
702 		return (EPERM);
703 
704 	sig = linux_to_bsd_signal(args->sig);
705 	ksiginfo_init(&ksi);
706 	error = lsiginfo_to_siginfo(td, &linfo, &ksi.ksi_info, sig);
707 	if (error != 0)
708 		return (error);
709 
710 	error = ESRCH;
711 	if ((p = pfind_any(args->pid)) != NULL) {
712 		error = p_cansignal(td, p, sig);
713 		if (error != 0) {
714 			PROC_UNLOCK(p);
715 			return (error);
716 		}
717 		error = tdsendsignal(p, NULL, sig, &ksi);
718 		PROC_UNLOCK(p);
719 	}
720 
721 	return (error);
722 }
723 
724 int
725 linux_rt_tgsigqueueinfo(struct thread *td, struct linux_rt_tgsigqueueinfo_args *args)
726 {
727 	l_siginfo_t linfo;
728 	struct thread *tds;
729 	ksiginfo_t ksi;
730 	int error;
731 	int sig;
732 
733 	if (!LINUX_SIG_VALID(args->sig))
734 		return (EINVAL);
735 
736 	error = copyin(args->uinfo, &linfo, sizeof(linfo));
737 	if (error != 0)
738 		return (error);
739 
740 	if (linfo.lsi_code >= 0)
741 		return (EPERM);
742 
743 	sig = linux_to_bsd_signal(args->sig);
744 	ksiginfo_init(&ksi);
745 	error = lsiginfo_to_siginfo(td, &linfo, &ksi.ksi_info, sig);
746 	if (error != 0)
747 		return (error);
748 
749 	tds = linux_tdfind(td, args->tid, args->tgid);
750 	if (tds == NULL)
751 		return (ESRCH);
752 
753 	return (linux_do_tkill(td, tds, &ksi));
754 }
755