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