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