svr4_signal.c revision 48620
1/*
2 * Copyright (c) 1998 Mark Newton
3 * Copyright (c) 1994 Christos Zoulas
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
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/param.h>
30#include <sys/systm.h>
31#include <sys/namei.h>
32#include <sys/proc.h>
33#include <sys/filedesc.h>
34#include <sys/mount.h>
35#include <sys/kernel.h>
36#include <sys/signal.h>
37#include <sys/signalvar.h>
38#include <sys/malloc.h>
39#include <sys/sysproto.h>
40
41#include <svr4/svr4.h>
42#include <svr4/svr4_types.h>
43#include <svr4/svr4_signal.h>
44#include <svr4/svr4_proto.h>
45#include <svr4/svr4_util.h>
46#include <svr4/svr4_ucontext.h>
47
48#define sigemptyset(s)		memset((s), 0, sizeof(*(s)))
49#define sigismember(s, n)	(*(s) & sigmask(n))
50#define sigaddset(s, n)		(*(s) |= sigmask(n))
51
52#define	svr4_sigmask(n)		(1 << (((n) - 1) & 31))
53#define	svr4_sigword(n)		(((n) - 1) >> 5)
54#define svr4_sigemptyset(s)	memset((s), 0, sizeof(*(s)))
55#define	svr4_sigismember(s, n)	((s)->bits[svr4_sigword(n)] & svr4_sigmask(n))
56#define	svr4_sigaddset(s, n)	((s)->bits[svr4_sigword(n)] |= svr4_sigmask(n))
57
58static __inline void svr4_sigfillset __P((svr4_sigset_t *));
59void svr4_to_bsd_sigaction __P((const struct svr4_sigaction *,
60				struct sigaction *));
61void bsd_to_svr4_sigaction __P((const struct sigaction *,
62				struct svr4_sigaction *));
63
64int bsd_to_svr4_sig[] = {
65	0,
66	SVR4_SIGHUP,
67	SVR4_SIGINT,
68	SVR4_SIGQUIT,
69	SVR4_SIGILL,
70	SVR4_SIGTRAP,
71	SVR4_SIGABRT,
72	SVR4_SIGEMT,
73	SVR4_SIGFPE,
74	SVR4_SIGKILL,
75	SVR4_SIGBUS,
76	SVR4_SIGSEGV,
77	SVR4_SIGSYS,
78	SVR4_SIGPIPE,
79	SVR4_SIGALRM,
80	SVR4_SIGTERM,
81	SVR4_SIGURG,
82	SVR4_SIGSTOP,
83	SVR4_SIGTSTP,
84	SVR4_SIGCONT,
85	SVR4_SIGCHLD,
86	SVR4_SIGTTIN,
87	SVR4_SIGTTOU,
88	SVR4_SIGIO,
89	SVR4_SIGXCPU,
90	SVR4_SIGXFSZ,
91	SVR4_SIGVTALRM,
92	SVR4_SIGPROF,
93	SVR4_SIGWINCH,
94	0,			/* SIGINFO */
95	SVR4_SIGUSR1,
96	SVR4_SIGUSR2,
97};
98
99int svr4_to_bsd_sig[] = {
100	0,
101	SIGHUP,
102	SIGINT,
103	SIGQUIT,
104	SIGILL,
105	SIGTRAP,
106	SIGABRT,
107	SIGEMT,
108	SIGFPE,
109	SIGKILL,
110	SIGBUS,
111	SIGSEGV,
112	SIGSYS,
113	SIGPIPE,
114	SIGALRM,
115	SIGTERM,
116	SIGUSR1,
117	SIGUSR2,
118	SIGCHLD,
119	0,		/* XXX NetBSD uses SIGPWR here, but we don't seem to have one */
120	SIGWINCH,
121	SIGURG,
122	SIGIO,
123	SIGSTOP,
124	SIGTSTP,
125	SIGCONT,
126	SIGTTIN,
127	SIGTTOU,
128	SIGVTALRM,
129	SIGPROF,
130	SIGXCPU,
131	SIGXFSZ,
132};
133
134static __inline void
135svr4_sigfillset(s)
136	svr4_sigset_t *s;
137{
138	int i;
139
140	svr4_sigemptyset(s);
141	for (i = 1; i < SVR4_NSIG; i++)
142		svr4_sigaddset(s, i);
143}
144
145void
146svr4_to_bsd_sigset(sss, bss)
147	const svr4_sigset_t *sss;
148	sigset_t *bss;
149{
150	int i, newsig;
151
152	sigemptyset(bss);
153	for (i = 1; i < SVR4_NSIG; i++) {
154		if (svr4_sigismember(sss, i)) {
155			newsig = svr4_to_bsd_sig[i];
156			if (newsig)
157				sigaddset(bss, newsig);
158		}
159	}
160}
161
162
163void
164bsd_to_svr4_sigset(bss, sss)
165	const sigset_t *bss;
166	svr4_sigset_t *sss;
167{
168	int i, newsig;
169
170	svr4_sigemptyset(sss);
171	for (i = 1; i < NSIG; i++) {
172		if (sigismember(bss, i)) {
173			newsig = bsd_to_svr4_sig[i];
174			if (newsig)
175				svr4_sigaddset(sss, newsig);
176		}
177	}
178}
179
180
181/*
182 * XXX: Only a subset of the flags is currently implemented.
183 */
184void
185svr4_to_bsd_sigaction(ssa, bsa)
186	const struct svr4_sigaction *ssa;
187	struct sigaction *bsa;
188{
189
190	bsa->sa_handler = (sig_t) ssa->ssa_handler;
191	svr4_to_bsd_sigset(&ssa->ssa_mask, &bsa->sa_mask);
192	bsa->sa_flags = 0;
193	if ((ssa->ssa_flags & SVR4_SA_ONSTACK) != 0)
194		bsa->sa_flags |= SA_ONSTACK;
195	if ((ssa->ssa_flags & SVR4_SA_RESETHAND) != 0)
196		bsa->sa_flags |= SA_RESETHAND;
197	if ((ssa->ssa_flags & SVR4_SA_RESTART) != 0)
198		bsa->sa_flags |= SA_RESTART;
199	if ((ssa->ssa_flags & SVR4_SA_SIGINFO) != 0)
200		DPRINTF(("svr4_to_bsd_sigaction: SA_SIGINFO ignored\n"));
201	if ((ssa->ssa_flags & SVR4_SA_NOCLDSTOP) != 0)
202		bsa->sa_flags |= SA_NOCLDSTOP;
203	if ((ssa->ssa_flags & SVR4_SA_NODEFER) != 0)
204		bsa->sa_flags |= SA_NODEFER;
205	if ((ssa->ssa_flags & SVR4_SA_NOCLDWAIT) != 0)
206		bsa->sa_flags |= SA_NOCLDWAIT;
207	if ((ssa->ssa_flags & ~SVR4_SA_ALLBITS) != 0)
208		DPRINTF(("svr4_to_bsd_sigaction: extra bits ignored\n"));
209}
210
211void
212bsd_to_svr4_sigaction(bsa, ssa)
213	const struct sigaction *bsa;
214	struct svr4_sigaction *ssa;
215{
216
217	ssa->ssa_handler = (svr4_sig_t) bsa->sa_handler;
218	bsd_to_svr4_sigset(&bsa->sa_mask, &ssa->ssa_mask);
219	ssa->ssa_flags = 0;
220	if ((bsa->sa_flags & SA_ONSTACK) != 0)
221		ssa->ssa_flags |= SVR4_SA_ONSTACK;
222	if ((bsa->sa_flags & SA_RESETHAND) != 0)
223		ssa->ssa_flags |= SVR4_SA_RESETHAND;
224	if ((bsa->sa_flags & SA_RESTART) != 0)
225		ssa->ssa_flags |= SVR4_SA_RESTART;
226	if ((bsa->sa_flags & SA_NODEFER) != 0)
227		ssa->ssa_flags |= SVR4_SA_NODEFER;
228	if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
229		ssa->ssa_flags |= SVR4_SA_NOCLDSTOP;
230}
231
232void
233svr4_to_bsd_sigaltstack(sss, bss)
234	const struct svr4_sigaltstack *sss;
235	struct sigaltstack *bss;
236{
237
238	bss->ss_sp = sss->ss_sp;
239	bss->ss_size = sss->ss_size;
240	bss->ss_flags = 0;
241	if ((sss->ss_flags & SVR4_SS_DISABLE) != 0)
242		bss->ss_flags |= SS_DISABLE;
243	if ((sss->ss_flags & SVR4_SS_ONSTACK) != 0)
244		bss->ss_flags |= SS_ONSTACK;
245	if ((sss->ss_flags & ~SVR4_SS_ALLBITS) != 0)
246	  /*XXX*/ uprintf("svr4_to_bsd_sigaltstack: extra bits ignored\n");
247}
248
249void
250bsd_to_svr4_sigaltstack(bss, sss)
251	const struct sigaltstack *bss;
252	struct svr4_sigaltstack *sss;
253{
254
255	sss->ss_sp = bss->ss_sp;
256	sss->ss_size = bss->ss_size;
257	sss->ss_flags = 0;
258	if ((bss->ss_flags & SS_DISABLE) != 0)
259		sss->ss_flags |= SVR4_SS_DISABLE;
260	if ((bss->ss_flags & SS_ONSTACK) != 0)
261		sss->ss_flags |= SVR4_SS_ONSTACK;
262}
263
264int
265svr4_sys_sigaction(p, uap)
266	register struct proc *p;
267	struct svr4_sys_sigaction_args *uap;
268{
269	struct svr4_sigaction *nisa, *oisa, tmpisa;
270	struct sigaction *nbsa, *obsa, tmpbsa;
271	struct sigaction_args sa;
272	caddr_t sg;
273	int error;
274
275	sg = stackgap_init();
276	nisa = SCARG(uap, nsa);
277	oisa = SCARG(uap, osa);
278
279	if (oisa != NULL)
280		obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
281	else
282		obsa = NULL;
283
284	if (nisa != NULL) {
285		nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
286		if ((error = copyin(nisa, &tmpisa, sizeof(tmpisa))) != 0)
287			return error;
288		svr4_to_bsd_sigaction(&tmpisa, &tmpbsa);
289		if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
290			return error;
291	} else
292		nbsa = NULL;
293
294	SCARG(&sa, signum) = svr4_to_bsd_sig[SCARG(uap, signum)];
295	SCARG(&sa, nsa) = nbsa;
296	SCARG(&sa, osa) = obsa;
297
298	if ((error = sigaction(p, &sa)) != 0)
299		return error;
300
301	if (oisa != NULL) {
302		if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
303			return error;
304		bsd_to_svr4_sigaction(&tmpbsa, &tmpisa);
305		if ((error = copyout(&tmpisa, oisa, sizeof(tmpisa))) != 0)
306			return error;
307	}
308
309	return 0;
310}
311
312int
313svr4_sys_sigaltstack(p, uap)
314	register struct proc *p;
315	struct svr4_sys_sigaltstack_args *uap;
316{
317	struct svr4_sigaltstack *nsss, *osss, tmpsss;
318	struct sigaltstack *nbss, *obss, tmpbss;
319	struct sigaltstack_args sa;
320	caddr_t sg;
321	int error, *retval;
322
323	retval = p->p_retval;
324	sg = stackgap_init();
325	nsss = SCARG(uap, nss);
326	osss = SCARG(uap, oss);
327
328	if (osss != NULL)
329		obss = stackgap_alloc(&sg, sizeof(struct sigaltstack));
330	else
331		obss = NULL;
332
333	if (nsss != NULL) {
334		nbss = stackgap_alloc(&sg, sizeof(struct sigaltstack));
335		if ((error = copyin(nsss, &tmpsss, sizeof(tmpsss))) != 0)
336			return error;
337		svr4_to_bsd_sigaltstack(&tmpsss, &tmpbss);
338		if ((error = copyout(&tmpbss, nbss, sizeof(tmpbss))) != 0)
339			return error;
340	} else
341		nbss = NULL;
342
343	SCARG(&sa, nss) = nbss;
344	SCARG(&sa, oss) = obss;
345
346	if ((error = sigaltstack(p, &sa)) != 0)
347		return error;
348
349	if (obss != NULL) {
350		if ((error = copyin(obss, &tmpbss, sizeof(tmpbss))) != 0)
351			return error;
352		bsd_to_svr4_sigaltstack(&tmpbss, &tmpsss);
353		if ((error = copyout(&tmpsss, osss, sizeof(tmpsss))) != 0)
354			return error;
355	}
356
357	return 0;
358}
359
360/*
361 * Stolen from the ibcs2 one
362 */
363int
364svr4_sys_signal(p, uap)
365	register struct proc *p;
366	struct svr4_sys_signal_args *uap;
367{
368	int signum = svr4_to_bsd_sig[SVR4_SIGNO(SCARG(uap, signum))];
369	int error, *retval;
370	caddr_t sg = stackgap_init();
371
372	retval = p->p_retval;
373	if (signum <= 0 || signum >= SVR4_NSIG)
374		return (EINVAL);
375
376	switch (SVR4_SIGCALL(SCARG(uap, signum))) {
377	case SVR4_SIGDEFER_MASK:
378		if (SCARG(uap, handler) == SVR4_SIG_HOLD)
379			goto sighold;
380		/* FALLTHROUGH */
381
382	case SVR4_SIGNAL_MASK:
383		{
384			struct sigaction_args sa_args;
385			struct sigaction *nbsa, *obsa, sa;
386
387			nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
388			obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
389			SCARG(&sa_args, signum) = signum;
390			SCARG(&sa_args, nsa) = nbsa;
391			SCARG(&sa_args, osa) = obsa;
392
393			sa.sa_handler = (sig_t) SCARG(uap, handler);
394			sigemptyset(&sa.sa_mask);
395			sa.sa_flags = 0;
396
397			if (signum != SIGALRM)
398				sa.sa_flags = SA_RESTART;
399
400			if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0)
401				return error;
402			if ((error = sigaction(p, &sa_args)) != 0) {
403				DPRINTF(("signal: sigaction failed: %d\n",
404					 error));
405				*retval = (int)SVR4_SIG_ERR;
406				return error;
407			}
408			if ((error = copyin(obsa, &sa, sizeof(sa))) != 0)
409				return error;
410			*retval = (int)sa.sa_handler;
411			return 0;
412		}
413
414	case SVR4_SIGHOLD_MASK:
415sighold:
416		{
417			struct sigprocmask_args sa;
418
419			SCARG(&sa, how) = SIG_BLOCK;
420			SCARG(&sa, mask) = sigmask(signum);
421			return sigprocmask(p, &sa);
422		}
423
424	case SVR4_SIGRELSE_MASK:
425		{
426			struct sigprocmask_args sa;
427
428			SCARG(&sa, how) = SIG_UNBLOCK;
429			SCARG(&sa, mask) = sigmask(signum);
430			return sigprocmask(p, &sa);
431		}
432
433	case SVR4_SIGIGNORE_MASK:
434		{
435			struct sigaction_args sa_args;
436			struct sigaction *bsa, sa;
437
438			bsa = stackgap_alloc(&sg, sizeof(struct sigaction));
439			SCARG(&sa_args, signum) = signum;
440			SCARG(&sa_args, nsa) = bsa;
441			SCARG(&sa_args, osa) = NULL;
442
443			sa.sa_handler = SIG_IGN;
444			sigemptyset(&sa.sa_mask);
445			sa.sa_flags = 0;
446			if ((error = copyout(&sa, bsa, sizeof(sa))) != 0)
447				return error;
448			if ((error = sigaction(p, &sa_args)) != 0) {
449				DPRINTF(("sigignore: sigaction failed\n"));
450				return error;
451			}
452			return 0;
453		}
454
455	case SVR4_SIGPAUSE_MASK:
456		{
457			struct sigsuspend_args sa;
458
459			SCARG(&sa, mask) = p->p_sigmask & ~sigmask(signum);
460			return sigsuspend(p, &sa);
461		}
462
463	default:
464		return (ENOSYS);
465	}
466}
467
468
469int
470svr4_sys_sigprocmask(p, uap)
471	struct proc *p;
472	struct svr4_sys_sigprocmask_args *uap;
473{
474	svr4_sigset_t sss;
475	sigset_t bss;
476	int error = 0, *retval;
477
478	retval = p->p_retval;
479	if (SCARG(uap, oset) != NULL) {
480		/* Fix the return value first if needed */
481		bsd_to_svr4_sigset(&p->p_sigmask, &sss);
482		if ((error = copyout(&sss, SCARG(uap, oset), sizeof(sss))) != 0)
483			return error;
484	}
485
486	if (SCARG(uap, set) == NULL)
487		/* Just examine */
488		return 0;
489
490	if ((error = copyin(SCARG(uap, set), &sss, sizeof(sss))) != 0)
491		return error;
492
493	svr4_to_bsd_sigset(&sss, &bss);
494
495	(void) splhigh();
496
497	switch (SCARG(uap, how)) {
498	case SVR4_SIG_BLOCK:
499		p->p_sigmask |= bss & ~sigcantmask;
500		break;
501
502	case SVR4_SIG_UNBLOCK:
503		p->p_sigmask &= ~bss;
504		break;
505
506	case SVR4_SIG_SETMASK:
507		p->p_sigmask = bss & ~sigcantmask;
508		break;
509
510	default:
511		error = EINVAL;
512		break;
513	}
514
515	(void) spl0();
516
517	return error;
518}
519
520int
521svr4_sys_sigpending(p, uap)
522	struct proc *p;
523	struct svr4_sys_sigpending_args *uap;
524{
525	sigset_t bss;
526	int *retval;
527	svr4_sigset_t sss;
528
529	retval = p->p_retval;
530	switch (SCARG(uap, what)) {
531	case 1:	/* sigpending */
532		if (SCARG(uap, mask) == NULL)
533			return 0;
534		bss = p->p_siglist & p->p_sigmask;
535		bsd_to_svr4_sigset(&bss, &sss);
536		break;
537
538	case 2:	/* sigfillset */
539		svr4_sigfillset(&sss);
540		break;
541
542	default:
543		return EINVAL;
544	}
545
546	return copyout(&sss, SCARG(uap, mask), sizeof(sss));
547}
548
549int
550svr4_sys_sigsuspend(p, uap)
551	register struct proc *p;
552	struct svr4_sys_sigsuspend_args *uap;
553{
554	svr4_sigset_t sss;
555	sigset_t bss;
556	struct sigsuspend_args sa;
557	int error;
558
559	if ((error = copyin(SCARG(uap, ss), &sss, sizeof(sss))) != 0)
560		return error;
561
562	svr4_to_bsd_sigset(&sss, &bss);
563
564	SCARG(&sa, mask) = bss;
565	return sigsuspend(p, &sa);
566}
567
568
569int
570svr4_sys_kill(p, uap)
571	register struct proc *p;
572	struct svr4_sys_kill_args *uap;
573{
574	struct kill_args ka;
575
576	SCARG(&ka, pid) = SCARG(uap, pid);
577	SCARG(&ka, signum) = svr4_to_bsd_sig[SCARG(uap, signum)];
578	return kill(p, &ka);
579}
580
581
582int
583svr4_sys_context(p, uap)
584	register struct proc *p;
585	struct svr4_sys_context_args *uap;
586{
587	struct svr4_ucontext uc;
588	int error;
589
590	switch (uap->func) {
591	case 0:
592		DPRINTF(("getcontext(%p)\n", uap->uc));
593		svr4_getcontext(p, &uc, p->p_sigmask,
594		    p->p_sigacts->ps_sigstk.ss_flags & SS_ONSTACK);
595		return copyout(&uc, uap->uc, sizeof(uc));
596
597	case 1:
598		DPRINTF(("setcontext(%p)\n", uap->uc));
599		if ((error = copyin(uap->uc, &uc, sizeof(uc))) != 0)
600			return error;
601		DPRINTF(("uc_flags = %x\n", uc.uc_flags));
602		DPRINTF(("uc_sigmask = %x\n", uc.uc_sigmask));
603
604		return svr4_setcontext(p, &uc);
605
606	default:
607		DPRINTF(("context(%d, %p)\n", uap->func,
608		    uap->uc));
609		return ENOSYS;
610	}
611	return 0;
612}
613
614int
615svr4_sys_pause(p, uap)
616	register struct proc *p;
617	struct svr4_sys_pause_args *uap;
618{
619	struct sigsuspend_args bsa;
620
621	SCARG(&bsa, mask) = p->p_sigmask;
622	return sigsuspend(p, &bsa);
623}
624