linux_signal.c revision 218720
1/*-
2 * Copyright (c) 1994-1995 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer
10 *    in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/compat/linux/linux_signal.c 218720 2011-02-15 21:46:36Z dchagin $");
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_signal.h>
54#include <compat/linux/linux_util.h>
55#include <compat/linux/linux_emul.h>
56
57void
58linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
59{
60	int b, l;
61
62	SIGEMPTYSET(*bss);
63	bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
64	bss->__bits[1] = lss->__bits[1];
65	for (l = 1; l <= LINUX_SIGTBLSZ; l++) {
66		if (LINUX_SIGISMEMBER(*lss, l)) {
67			b = linux_to_bsd_signal[_SIG_IDX(l)];
68			if (b)
69				SIGADDSET(*bss, b);
70		}
71	}
72}
73
74void
75bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
76{
77	int b, l;
78
79	LINUX_SIGEMPTYSET(*lss);
80	lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
81	lss->__bits[1] = bss->__bits[1];
82	for (b = 1; b <= LINUX_SIGTBLSZ; b++) {
83		if (SIGISMEMBER(*bss, b)) {
84			l = bsd_to_linux_signal[_SIG_IDX(b)];
85			if (l)
86				LINUX_SIGADDSET(*lss, l);
87		}
88	}
89}
90
91static void
92linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
93{
94
95	linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask);
96	bsa->sa_handler = PTRIN(lsa->lsa_handler);
97	bsa->sa_flags = 0;
98	if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP)
99		bsa->sa_flags |= SA_NOCLDSTOP;
100	if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT)
101		bsa->sa_flags |= SA_NOCLDWAIT;
102	if (lsa->lsa_flags & LINUX_SA_SIGINFO)
103		bsa->sa_flags |= SA_SIGINFO;
104	if (lsa->lsa_flags & LINUX_SA_ONSTACK)
105		bsa->sa_flags |= SA_ONSTACK;
106	if (lsa->lsa_flags & LINUX_SA_RESTART)
107		bsa->sa_flags |= SA_RESTART;
108	if (lsa->lsa_flags & LINUX_SA_ONESHOT)
109		bsa->sa_flags |= SA_RESETHAND;
110	if (lsa->lsa_flags & LINUX_SA_NOMASK)
111		bsa->sa_flags |= SA_NODEFER;
112}
113
114static void
115bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa)
116{
117
118	bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask);
119#ifdef COMPAT_LINUX32
120	lsa->lsa_handler = (uintptr_t)bsa->sa_handler;
121#else
122	lsa->lsa_handler = bsa->sa_handler;
123#endif
124	lsa->lsa_restorer = 0;		/* unsupported */
125	lsa->lsa_flags = 0;
126	if (bsa->sa_flags & SA_NOCLDSTOP)
127		lsa->lsa_flags |= LINUX_SA_NOCLDSTOP;
128	if (bsa->sa_flags & SA_NOCLDWAIT)
129		lsa->lsa_flags |= LINUX_SA_NOCLDWAIT;
130	if (bsa->sa_flags & SA_SIGINFO)
131		lsa->lsa_flags |= LINUX_SA_SIGINFO;
132	if (bsa->sa_flags & SA_ONSTACK)
133		lsa->lsa_flags |= LINUX_SA_ONSTACK;
134	if (bsa->sa_flags & SA_RESTART)
135		lsa->lsa_flags |= LINUX_SA_RESTART;
136	if (bsa->sa_flags & SA_RESETHAND)
137		lsa->lsa_flags |= LINUX_SA_ONESHOT;
138	if (bsa->sa_flags & SA_NODEFER)
139		lsa->lsa_flags |= LINUX_SA_NOMASK;
140}
141
142int
143linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa,
144		   l_sigaction_t *linux_osa)
145{
146	struct sigaction act, oact, *nsa, *osa;
147	int error, sig;
148
149	if (!LINUX_SIG_VALID(linux_sig))
150		return (EINVAL);
151
152	osa = (linux_osa != NULL) ? &oact : NULL;
153	if (linux_nsa != NULL) {
154		nsa = &act;
155		linux_to_bsd_sigaction(linux_nsa, nsa);
156	} else
157		nsa = NULL;
158
159	if (linux_sig <= LINUX_SIGTBLSZ)
160		sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)];
161	else
162		sig = linux_sig;
163
164	error = kern_sigaction(td, sig, nsa, osa, 0);
165	if (error)
166		return (error);
167
168	if (linux_osa != NULL)
169		bsd_to_linux_sigaction(osa, linux_osa);
170
171	return (0);
172}
173
174
175int
176linux_signal(struct thread *td, struct linux_signal_args *args)
177{
178	l_sigaction_t nsa, osa;
179	int error;
180
181#ifdef DEBUG
182	if (ldebug(signal))
183		printf(ARGS(signal, "%d, %p"),
184		    args->sig, (void *)(uintptr_t)args->handler);
185#endif
186
187	nsa.lsa_handler = args->handler;
188	nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK;
189	LINUX_SIGEMPTYSET(nsa.lsa_mask);
190
191	error = linux_do_sigaction(td, args->sig, &nsa, &osa);
192	td->td_retval[0] = (int)(intptr_t)osa.lsa_handler;
193
194	return (error);
195}
196
197int
198linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args)
199{
200	l_sigaction_t nsa, osa;
201	int error;
202
203#ifdef DEBUG
204	if (ldebug(rt_sigaction))
205		printf(ARGS(rt_sigaction, "%ld, %p, %p, %ld"),
206		    (long)args->sig, (void *)args->act,
207		    (void *)args->oact, (long)args->sigsetsize);
208#endif
209
210	if (args->sigsetsize != sizeof(l_sigset_t))
211		return (EINVAL);
212
213	if (args->act != NULL) {
214		error = copyin(args->act, &nsa, sizeof(l_sigaction_t));
215		if (error)
216			return (error);
217	}
218
219	error = linux_do_sigaction(td, args->sig,
220				   args->act ? &nsa : NULL,
221				   args->oact ? &osa : NULL);
222
223	if (args->oact != NULL && !error) {
224		error = copyout(&osa, args->oact, sizeof(l_sigaction_t));
225	}
226
227	return (error);
228}
229
230static int
231linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new,
232		     l_sigset_t *old)
233{
234	sigset_t omask, nmask;
235	sigset_t *nmaskp;
236	int error;
237
238	td->td_retval[0] = 0;
239
240	switch (how) {
241	case LINUX_SIG_BLOCK:
242		how = SIG_BLOCK;
243		break;
244	case LINUX_SIG_UNBLOCK:
245		how = SIG_UNBLOCK;
246		break;
247	case LINUX_SIG_SETMASK:
248		how = SIG_SETMASK;
249		break;
250	default:
251		return (EINVAL);
252	}
253	if (new != NULL) {
254		linux_to_bsd_sigset(new, &nmask);
255		nmaskp = &nmask;
256	} else
257		nmaskp = NULL;
258	error = kern_sigprocmask(td, how, nmaskp, &omask, 0);
259	if (error == 0 && old != NULL)
260		bsd_to_linux_sigset(&omask, old);
261
262	return (error);
263}
264
265int
266linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args)
267{
268	l_osigset_t mask;
269	l_sigset_t set, oset;
270	int error;
271
272#ifdef DEBUG
273	if (ldebug(sigprocmask))
274		printf(ARGS(sigprocmask, "%d, *, *"), args->how);
275#endif
276
277	if (args->mask != NULL) {
278		error = copyin(args->mask, &mask, sizeof(l_osigset_t));
279		if (error)
280			return (error);
281		LINUX_SIGEMPTYSET(set);
282		set.__bits[0] = mask;
283	}
284
285	error = linux_do_sigprocmask(td, args->how,
286				     args->mask ? &set : NULL,
287				     args->omask ? &oset : NULL);
288
289	if (args->omask != NULL && !error) {
290		mask = oset.__bits[0];
291		error = copyout(&mask, args->omask, sizeof(l_osigset_t));
292	}
293
294	return (error);
295}
296
297int
298linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args)
299{
300	l_sigset_t set, oset;
301	int error;
302
303#ifdef DEBUG
304	if (ldebug(rt_sigprocmask))
305		printf(ARGS(rt_sigprocmask, "%d, %p, %p, %ld"),
306		    args->how, (void *)args->mask,
307		    (void *)args->omask, (long)args->sigsetsize);
308#endif
309
310	if (args->sigsetsize != sizeof(l_sigset_t))
311		return EINVAL;
312
313	if (args->mask != NULL) {
314		error = copyin(args->mask, &set, sizeof(l_sigset_t));
315		if (error)
316			return (error);
317	}
318
319	error = linux_do_sigprocmask(td, args->how,
320				     args->mask ? &set : NULL,
321				     args->omask ? &oset : NULL);
322
323	if (args->omask != NULL && !error) {
324		error = copyout(&oset, args->omask, sizeof(l_sigset_t));
325	}
326
327	return (error);
328}
329
330int
331linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args)
332{
333	struct proc *p = td->td_proc;
334	l_sigset_t mask;
335
336#ifdef DEBUG
337	if (ldebug(sgetmask))
338		printf(ARGS(sgetmask, ""));
339#endif
340
341	PROC_LOCK(p);
342	bsd_to_linux_sigset(&td->td_sigmask, &mask);
343	PROC_UNLOCK(p);
344	td->td_retval[0] = mask.__bits[0];
345	return (0);
346}
347
348int
349linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args)
350{
351	struct proc *p = td->td_proc;
352	l_sigset_t lset;
353	sigset_t bset;
354
355#ifdef DEBUG
356	if (ldebug(ssetmask))
357		printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask);
358#endif
359
360	PROC_LOCK(p);
361	bsd_to_linux_sigset(&td->td_sigmask, &lset);
362	td->td_retval[0] = lset.__bits[0];
363	LINUX_SIGEMPTYSET(lset);
364	lset.__bits[0] = args->mask;
365	linux_to_bsd_sigset(&lset, &bset);
366	td->td_sigmask = bset;
367	SIG_CANTMASK(td->td_sigmask);
368	signotify(td);
369	PROC_UNLOCK(p);
370	return (0);
371}
372
373/*
374 * MPSAFE
375 */
376int
377linux_sigpending(struct thread *td, struct linux_sigpending_args *args)
378{
379	struct proc *p = td->td_proc;
380	sigset_t bset;
381	l_sigset_t lset;
382	l_osigset_t mask;
383
384#ifdef DEBUG
385	if (ldebug(sigpending))
386		printf(ARGS(sigpending, "*"));
387#endif
388
389	PROC_LOCK(p);
390	bset = p->p_siglist;
391	SIGSETOR(bset, td->td_siglist);
392	SIGSETAND(bset, td->td_sigmask);
393	PROC_UNLOCK(p);
394	bsd_to_linux_sigset(&bset, &lset);
395	mask = lset.__bits[0];
396	return (copyout(&mask, args->mask, sizeof(mask)));
397}
398
399/*
400 * MPSAFE
401 */
402int
403linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args)
404{
405	struct proc *p = td->td_proc;
406	sigset_t bset;
407	l_sigset_t lset;
408
409	if (args->sigsetsize > sizeof(lset))
410		return EINVAL;
411		/* NOT REACHED */
412
413#ifdef DEBUG
414	if (ldebug(rt_sigpending))
415		printf(ARGS(rt_sigpending, "*"));
416#endif
417
418	PROC_LOCK(p);
419	bset = p->p_siglist;
420	SIGSETOR(bset, td->td_siglist);
421	SIGSETAND(bset, td->td_sigmask);
422	PROC_UNLOCK(p);
423	bsd_to_linux_sigset(&bset, &lset);
424	return (copyout(&lset, args->set, args->sigsetsize));
425}
426
427/*
428 * MPSAFE
429 */
430int
431linux_rt_sigtimedwait(struct thread *td,
432	struct linux_rt_sigtimedwait_args *args)
433{
434	int error, sig;
435	l_timeval ltv;
436	struct timeval tv;
437	struct timespec ts, *tsa;
438	l_sigset_t lset;
439	sigset_t bset;
440	l_siginfo_t linfo;
441	ksiginfo_t info;
442
443#ifdef DEBUG
444	if (ldebug(rt_sigtimedwait))
445		printf(ARGS(rt_sigtimedwait, "*"));
446#endif
447	if (args->sigsetsize != sizeof(l_sigset_t))
448		return (EINVAL);
449
450	if ((error = copyin(args->mask, &lset, sizeof(lset))))
451		return (error);
452	linux_to_bsd_sigset(&lset, &bset);
453
454	tsa = NULL;
455	if (args->timeout) {
456		if ((error = copyin(args->timeout, &ltv, sizeof(ltv))))
457			return (error);
458#ifdef DEBUG
459		if (ldebug(rt_sigtimedwait))
460			printf(LMSG("linux_rt_sigtimedwait: "
461			    "incoming timeout (%d/%d)\n"),
462			    ltv.tv_sec, ltv.tv_usec);
463#endif
464		tv.tv_sec = (long)ltv.tv_sec;
465		tv.tv_usec = (suseconds_t)ltv.tv_usec;
466		if (itimerfix(&tv)) {
467			/*
468			 * The timeout was invalid. Convert it to something
469			 * valid that will act as it does under Linux.
470			 */
471			tv.tv_sec += tv.tv_usec / 1000000;
472			tv.tv_usec %= 1000000;
473			if (tv.tv_usec < 0) {
474				tv.tv_sec -= 1;
475				tv.tv_usec += 1000000;
476			}
477			if (tv.tv_sec < 0)
478				timevalclear(&tv);
479#ifdef DEBUG
480			if (ldebug(rt_sigtimedwait))
481				printf(LMSG("linux_rt_sigtimedwait: "
482				    "converted timeout (%jd/%ld)\n"),
483				    (intmax_t)tv.tv_sec, tv.tv_usec);
484#endif
485		}
486		TIMEVAL_TO_TIMESPEC(&tv, &ts);
487		tsa = &ts;
488	}
489	error = kern_sigtimedwait(td, bset, &info, tsa);
490#ifdef DEBUG
491	if (ldebug(rt_sigtimedwait))
492		printf(LMSG("linux_rt_sigtimedwait: "
493		    "sigtimedwait returning (%d)\n"), error);
494#endif
495	if (error)
496		return (error);
497
498	sig = BSD_TO_LINUX_SIGNAL(info.ksi_signo);
499
500	if (args->ptr) {
501		memset(&linfo, 0, sizeof(linfo));
502		ksiginfo_to_lsiginfo(&info, &linfo, sig);
503		error = copyout(&linfo, args->ptr, sizeof(linfo));
504	}
505	if (error == 0)
506		td->td_retval[0] = sig;
507
508	return (error);
509}
510
511int
512linux_kill(struct thread *td, struct linux_kill_args *args)
513{
514	struct kill_args /* {
515	    int pid;
516	    int signum;
517	} */ tmp;
518
519#ifdef DEBUG
520	if (ldebug(kill))
521		printf(ARGS(kill, "%d, %d"), args->pid, args->signum);
522#endif
523
524	/*
525	 * Allow signal 0 as a means to check for privileges
526	 */
527	if (!LINUX_SIG_VALID(args->signum) && args->signum != 0)
528		return (EINVAL);
529
530	if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ)
531		tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)];
532	else
533		tmp.signum = args->signum;
534
535	tmp.pid = args->pid;
536	return (kill(td, &tmp));
537}
538
539static int
540linux_do_tkill(struct thread *td, l_int tgid, l_int pid, l_int signum)
541{
542	struct proc *proc = td->td_proc;
543	struct linux_emuldata *em;
544	struct proc *p;
545	ksiginfo_t ksi;
546	int error;
547
548	AUDIT_ARG_SIGNUM(signum);
549	AUDIT_ARG_PID(pid);
550
551	/*
552	 * Allow signal 0 as a means to check for privileges
553	 */
554	if (!LINUX_SIG_VALID(signum) && signum != 0)
555		return (EINVAL);
556
557	if (signum > 0 && signum <= LINUX_SIGTBLSZ)
558		signum = linux_to_bsd_signal[_SIG_IDX(signum)];
559
560	if ((p = pfind(pid)) == NULL) {
561		if ((p = zpfind(pid)) == NULL)
562			return (ESRCH);
563	}
564
565	AUDIT_ARG_PROCESS(p);
566	error = p_cansignal(td, p, signum);
567	if (error != 0 || signum == 0)
568		goto out;
569
570	error = ESRCH;
571	em = em_find(p, EMUL_DONTLOCK);
572
573	if (em == NULL) {
574#ifdef DEBUG
575		printf("emuldata not found in do_tkill.\n");
576#endif
577		goto out;
578	}
579	if (tgid > 0 && em->shared->group_pid != tgid)
580		goto out;
581
582	ksiginfo_init(&ksi);
583	ksi.ksi_signo = signum;
584	ksi.ksi_code = LINUX_SI_TKILL;
585	ksi.ksi_errno = 0;
586	ksi.ksi_pid = proc->p_pid;
587	ksi.ksi_uid = proc->p_ucred->cr_ruid;
588
589	error = pksignal(p, ksi.ksi_signo, &ksi);
590
591out:
592	PROC_UNLOCK(p);
593	return (error);
594}
595
596int
597linux_tgkill(struct thread *td, struct linux_tgkill_args *args)
598{
599
600#ifdef DEBUG
601	if (ldebug(tgkill))
602		printf(ARGS(tgkill, "%d, %d, %d"), args->tgid, args->pid, args->sig);
603#endif
604	if (args->pid <= 0 || args->tgid <=0)
605		return (EINVAL);
606
607	return (linux_do_tkill(td, args->tgid, args->pid, args->sig));
608}
609
610int
611linux_tkill(struct thread *td, struct linux_tkill_args *args)
612{
613#ifdef DEBUG
614	if (ldebug(tkill))
615		printf(ARGS(tkill, "%i, %i"), args->tid, args->sig);
616#endif
617	if (args->tid <= 0)
618		return (EINVAL);
619
620	return (linux_do_tkill(td, 0, args->tid, args->sig));
621}
622
623void
624ksiginfo_to_lsiginfo(ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig)
625{
626
627	lsi->lsi_signo = sig;
628	lsi->lsi_code = ksi->ksi_code;
629
630	switch (sig) {
631	case LINUX_SIGPOLL:
632		/* XXX si_fd? */
633		lsi->lsi_band = ksi->ksi_band;
634		break;
635	case LINUX_SIGCHLD:
636		lsi->lsi_pid = ksi->ksi_pid;
637		lsi->lsi_uid = ksi->ksi_uid;
638		lsi->lsi_status = ksi->ksi_status;
639		break;
640	case LINUX_SIGBUS:
641	case LINUX_SIGILL:
642	case LINUX_SIGFPE:
643	case LINUX_SIGSEGV:
644		lsi->lsi_addr = PTROUT(ksi->ksi_addr);
645		break;
646	default:
647		/* XXX SI_TIMER etc... */
648		lsi->lsi_pid = ksi->ksi_pid;
649		lsi->lsi_uid = ksi->ksi_uid;
650		break;
651	}
652	if (sig >= LINUX_SIGRTMIN) {
653		lsi->lsi_int = ksi->ksi_info.si_value.sival_int;
654		lsi->lsi_ptr = PTROUT(ksi->ksi_info.si_value.sival_ptr);
655	}
656}
657