netbsd32_signal.c revision 1.39.2.1 1 /* $NetBSD: netbsd32_signal.c,v 1.39.2.1 2016/11/04 14:49:07 pgoyette Exp $ */
2
3 /*
4 * Copyright (c) 1998, 2001 Matthew R. Green
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 ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * 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 __KERNEL_RCSID(0, "$NetBSD: netbsd32_signal.c,v 1.39.2.1 2016/11/04 14:49:07 pgoyette Exp $");
31
32 #if defined(_KERNEL_OPT)
33 #include "opt_ktrace.h"
34 #endif
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/mount.h>
39 #include <sys/stat.h>
40 #include <sys/time.h>
41 #include <sys/signalvar.h>
42 #include <sys/proc.h>
43 #include <sys/wait.h>
44 #include <sys/dirent.h>
45
46 #include <uvm/uvm_extern.h>
47
48 #include <compat/netbsd32/netbsd32.h>
49 #include <compat/netbsd32/netbsd32_conv.h>
50 #include <compat/netbsd32/netbsd32_syscallargs.h>
51
52 #include <compat/sys/signal.h>
53 #include <compat/sys/signalvar.h>
54 #include <compat/sys/siginfo.h>
55 #include <compat/sys/ucontext.h>
56 #include <compat/common/compat_sigaltstack.h>
57
58 int
59 netbsd32_sigaction(struct lwp *l, const struct netbsd32_sigaction_args *uap, register_t *retval)
60 {
61 /* {
62 syscallarg(int) signum;
63 syscallarg(const netbsd32_sigactionp_t) nsa;
64 syscallarg(netbsd32_sigactionp_t) osa;
65 } */
66 struct sigaction nsa, osa;
67 struct netbsd32_sigaction13 *sa32p, sa32;
68 int error;
69
70 if (SCARG_P32(uap, nsa)) {
71 sa32p = SCARG_P32(uap, nsa);
72 if (copyin(sa32p, &sa32, sizeof(sa32)))
73 return EFAULT;
74 nsa.sa_handler = (void *)NETBSD32PTR64(sa32.netbsd32_sa_handler);
75 memset(&nsa.sa_mask, 0, sizeof(nsa.sa_mask));
76 nsa.sa_mask.__bits[0] = sa32.netbsd32_sa_mask;
77 nsa.sa_flags = sa32.netbsd32_sa_flags;
78 }
79 error = sigaction1(l, SCARG(uap, signum),
80 SCARG_P32(uap, nsa) ? &nsa : 0,
81 SCARG_P32(uap, osa) ? &osa : 0,
82 NULL, 0);
83
84 if (error)
85 return (error);
86
87 if (SCARG_P32(uap, osa)) {
88 NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler);
89 sa32.netbsd32_sa_mask = osa.sa_mask.__bits[0];
90 sa32.netbsd32_sa_flags = osa.sa_flags;
91 sa32p = SCARG_P32(uap, osa);
92 if (copyout(&sa32, sa32p, sizeof(sa32)))
93 return EFAULT;
94 }
95
96 return (0);
97 }
98
99 int
100 netbsd32___sigaltstack14(struct lwp *l, const struct netbsd32___sigaltstack14_args *uap, register_t *retval)
101 {
102 /* {
103 syscallarg(const netbsd32_sigaltstackp_t) nss;
104 syscallarg(netbsd32_sigaltstackp_t) oss;
105 } */
106 compat_sigaltstack(uap, netbsd32_sigaltstack, SS_ONSTACK, SS_DISABLE);
107 }
108
109 /* ARGSUSED */
110 int
111 netbsd32___sigaction14(struct lwp *l, const struct netbsd32___sigaction14_args *uap, register_t *retval)
112 {
113 /* {
114 syscallarg(int) signum;
115 syscallarg(const struct sigaction *) nsa;
116 syscallarg(struct sigaction *) osa;
117 } */
118 struct netbsd32_sigaction sa32;
119 struct sigaction nsa, osa;
120 int error;
121
122 if (SCARG_P32(uap, nsa)) {
123 error = copyin(SCARG_P32(uap, nsa), &sa32, sizeof(sa32));
124 if (error)
125 return (error);
126 nsa.sa_handler = NETBSD32PTR64(sa32.netbsd32_sa_handler);
127 nsa.sa_mask = sa32.netbsd32_sa_mask;
128 nsa.sa_flags = sa32.netbsd32_sa_flags;
129 }
130 error = sigaction1(l, SCARG(uap, signum),
131 SCARG_P32(uap, nsa) ? &nsa : 0,
132 SCARG_P32(uap, osa) ? &osa : 0,
133 NULL, 0);
134 if (error)
135 return (error);
136 if (SCARG_P32(uap, osa)) {
137 NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler);
138 sa32.netbsd32_sa_mask = osa.sa_mask;
139 sa32.netbsd32_sa_flags = osa.sa_flags;
140 error = copyout(&sa32, SCARG_P32(uap, osa), sizeof(sa32));
141 if (error)
142 return (error);
143 }
144 return (0);
145 }
146
147 /* ARGSUSED */
148 int
149 netbsd32___sigaction_sigtramp(struct lwp *l, const struct netbsd32___sigaction_sigtramp_args *uap, register_t *retval)
150 {
151 /* {
152 syscallarg(int) signum;
153 syscallarg(const netbsd32_sigactionp_t) nsa;
154 syscallarg(netbsd32_sigactionp_t) osa;
155 syscallarg(netbsd32_voidp) tramp;
156 syscallarg(int) vers;
157 } */
158 struct netbsd32_sigaction sa32;
159 struct sigaction nsa, osa;
160 int error;
161
162 if (SCARG_P32(uap, nsa)) {
163 error = copyin(SCARG_P32(uap, nsa), &sa32, sizeof(sa32));
164 if (error)
165 return (error);
166 nsa.sa_handler = NETBSD32PTR64(sa32.netbsd32_sa_handler);
167 nsa.sa_mask = sa32.netbsd32_sa_mask;
168 nsa.sa_flags = sa32.netbsd32_sa_flags;
169 }
170 error = sigaction1(l, SCARG(uap, signum),
171 SCARG_P32(uap, nsa) ? &nsa : 0,
172 SCARG_P32(uap, osa) ? &osa : 0,
173 SCARG_P32(uap, tramp), SCARG(uap, vers));
174 if (error)
175 return (error);
176 if (SCARG_P32(uap, osa)) {
177 NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler);
178 sa32.netbsd32_sa_mask = osa.sa_mask;
179 sa32.netbsd32_sa_flags = osa.sa_flags;
180 error = copyout(&sa32, SCARG_P32(uap, osa), sizeof(sa32));
181 if (error)
182 return (error);
183 }
184 return (0);
185 }
186
187 void
188 netbsd32_ksi32_to_ksi(struct _ksiginfo *si, const struct __ksiginfo32 *si32)
189 {
190 memset(si, 0, sizeof (*si));
191 si->_signo = si32->_signo;
192 si->_code = si32->_code;
193 si->_errno = si32->_errno;
194
195 switch (si32->_signo) {
196 case SIGILL:
197 case SIGBUS:
198 case SIGSEGV:
199 case SIGFPE:
200 case SIGTRAP:
201 si->_reason._fault._addr =
202 NETBSD32IPTR64(si32->_reason._fault._addr);
203 si->_reason._fault._trap = si32->_reason._fault._trap;
204 break;
205 case SIGALRM:
206 case SIGVTALRM:
207 case SIGPROF:
208 default: /* see sigqueue() and kill1() */
209 si->_reason._rt._pid = si32->_reason._rt._pid;
210 si->_reason._rt._uid = si32->_reason._rt._uid;
211 si->_reason._rt._value.sival_int =
212 si32->_reason._rt._value.sival_int;
213 break;
214 case SIGCHLD:
215 si->_reason._child._pid = si32->_reason._child._pid;
216 si->_reason._child._uid = si32->_reason._child._uid;
217 si->_reason._child._utime = si32->_reason._child._utime;
218 si->_reason._child._stime = si32->_reason._child._stime;
219 break;
220 case SIGURG:
221 case SIGIO:
222 si->_reason._poll._band = si32->_reason._poll._band;
223 si->_reason._poll._fd = si32->_reason._poll._fd;
224 break;
225 }
226 }
227
228 #ifdef KTRACE
229 static void
230 netbsd32_ksi_to_ksi32(struct __ksiginfo32 *si32, const struct _ksiginfo *si)
231 {
232 memset(si32, 0, sizeof (*si32));
233 si32->_signo = si->_signo;
234 si32->_code = si->_code;
235 si32->_errno = si->_errno;
236
237 switch (si->_signo) {
238 case SIGILL:
239 case SIGBUS:
240 case SIGSEGV:
241 case SIGFPE:
242 case SIGTRAP:
243 si32->_reason._fault._addr =
244 NETBSD32PTR32I(si->_reason._fault._addr);
245 si32->_reason._fault._trap = si->_reason._fault._trap;
246 break;
247 case SIGALRM:
248 case SIGVTALRM:
249 case SIGPROF:
250 default: /* see sigqueue() and kill1() */
251 si32->_reason._rt._pid = si->_reason._rt._pid;
252 si32->_reason._rt._uid = si->_reason._rt._uid;
253 si32->_reason._rt._value.sival_int =
254 si->_reason._rt._value.sival_int;
255 break;
256 case SIGCHLD:
257 si32->_reason._child._pid = si->_reason._child._pid;
258 si32->_reason._child._uid = si->_reason._child._uid;
259 si32->_reason._child._utime = si->_reason._child._utime;
260 si32->_reason._child._stime = si->_reason._child._stime;
261 break;
262 case SIGURG:
263 case SIGIO:
264 si32->_reason._poll._band = si->_reason._poll._band;
265 si32->_reason._poll._fd = si->_reason._poll._fd;
266 break;
267 }
268 }
269 #endif
270
271 void
272 netbsd32_si_to_si32(siginfo32_t *si32, const siginfo_t *si)
273 {
274 memset(si32, 0, sizeof (*si32));
275 si32->si_signo = si->si_signo;
276 si32->si_code = si->si_code;
277 si32->si_errno = si->si_errno;
278
279 switch (si32->si_signo) {
280 case 0: /* SA */
281 si32->si_value.sival_int = si->si_value.sival_int;
282 break;
283 case SIGILL:
284 case SIGBUS:
285 case SIGSEGV:
286 case SIGFPE:
287 case SIGTRAP:
288 si32->si_addr = (uint32_t)(uintptr_t)si->si_addr;
289 si32->si_trap = si->si_trap;
290 break;
291 case SIGALRM:
292 case SIGVTALRM:
293 case SIGPROF:
294 default:
295 si32->si_pid = si->si_pid;
296 si32->si_uid = si->si_uid;
297 si32->si_value.sival_int = si->si_value.sival_int;
298 break;
299 case SIGCHLD:
300 si32->si_pid = si->si_pid;
301 si32->si_uid = si->si_uid;
302 si32->si_status = si->si_status;
303 si32->si_utime = si->si_utime;
304 si32->si_stime = si->si_stime;
305 break;
306 case SIGURG:
307 case SIGIO:
308 si32->si_band = si->si_band;
309 si32->si_fd = si->si_fd;
310 break;
311 }
312 }
313
314 void
315 getucontext32(struct lwp *l, ucontext32_t *ucp)
316 {
317 struct proc *p = l->l_proc;
318
319 KASSERT(mutex_owned(p->p_lock));
320
321 ucp->uc_flags = 0;
322 ucp->uc_link = (uint32_t)(intptr_t)l->l_ctxlink;
323 ucp->uc_sigmask = l->l_sigmask;
324 ucp->uc_flags |= _UC_SIGMASK;
325
326 /*
327 * The (unsupplied) definition of the `current execution stack'
328 * in the System V Interface Definition appears to allow returning
329 * the main context stack.
330 */
331 if ((l->l_sigstk.ss_flags & SS_ONSTACK) == 0) {
332 ucp->uc_stack.ss_sp = USRSTACK32;
333 ucp->uc_stack.ss_size = ctob(p->p_vmspace->vm_ssize);
334 ucp->uc_stack.ss_flags = 0; /* XXX, def. is Very Fishy */
335 } else {
336 /* Simply copy alternate signal execution stack. */
337 ucp->uc_stack.ss_sp =
338 (uint32_t)(intptr_t)l->l_sigstk.ss_sp;
339 ucp->uc_stack.ss_size = l->l_sigstk.ss_size;
340 ucp->uc_stack.ss_flags = l->l_sigstk.ss_flags;
341 }
342 ucp->uc_flags |= _UC_STACK;
343 mutex_exit(p->p_lock);
344 cpu_getmcontext32(l, &ucp->uc_mcontext, &ucp->uc_flags);
345 mutex_enter(p->p_lock);
346 }
347
348 int
349 netbsd32_getcontext(struct lwp *l, const struct netbsd32_getcontext_args *uap, register_t *retval)
350 {
351 /* {
352 syscallarg(netbsd32_ucontextp) ucp;
353 } */
354 struct proc *p = l->l_proc;
355 ucontext32_t uc;
356
357 memset(&uc, 0, sizeof(uc));
358
359 mutex_enter(p->p_lock);
360 getucontext32(l, &uc);
361 mutex_exit(p->p_lock);
362
363 return copyout(&uc, SCARG_P32(uap, ucp), sizeof (ucontext32_t));
364 }
365
366 int
367 setucontext32(struct lwp *l, const ucontext32_t *ucp)
368 {
369 struct proc *p = l->l_proc;
370 int error;
371
372 KASSERT(mutex_owned(p->p_lock));
373
374 if ((ucp->uc_flags & _UC_SIGMASK) != 0) {
375 error = sigprocmask1(l, SIG_SETMASK, &ucp->uc_sigmask, NULL);
376 if (error != 0)
377 return error;
378 }
379
380 mutex_exit(p->p_lock);
381 error = cpu_setmcontext32(l, &ucp->uc_mcontext, ucp->uc_flags);
382 mutex_enter(p->p_lock);
383 if (error != 0)
384 return (error);
385
386 l->l_ctxlink = (void *)(intptr_t)ucp->uc_link;
387
388 /*
389 * If there was stack information, update whether or not we are
390 * still running on an alternate signal stack.
391 */
392 if ((ucp->uc_flags & _UC_STACK) != 0) {
393 if (ucp->uc_stack.ss_flags & SS_ONSTACK)
394 l->l_sigstk.ss_flags |= SS_ONSTACK;
395 else
396 l->l_sigstk.ss_flags &= ~SS_ONSTACK;
397 }
398
399 return 0;
400 }
401
402 /* ARGSUSED */
403 int
404 netbsd32_setcontext(struct lwp *l, const struct netbsd32_setcontext_args *uap, register_t *retval)
405 {
406 /* {
407 syscallarg(netbsd32_ucontextp) ucp;
408 } */
409 ucontext32_t uc;
410 int error;
411 struct proc *p = l->l_proc;
412
413 error = copyin(SCARG_P32(uap, ucp), &uc, sizeof (uc));
414 if (error)
415 return (error);
416 if (!(uc.uc_flags & _UC_CPU))
417 return (EINVAL);
418 mutex_enter(p->p_lock);
419 error = setucontext32(l, &uc);
420 mutex_exit(p->p_lock);
421 if (error)
422 return (error);
423
424 return (EJUSTRETURN);
425 }
426
427 static int
428 netbsd32_sigtimedwait_put_info(const void *src, void *dst, size_t size)
429 {
430 const siginfo_t *info = src;
431 siginfo32_t info32;
432
433 netbsd32_si_to_si32(&info32, info);
434
435 return copyout(&info32, dst, sizeof(info32));
436 }
437
438 static int
439 netbsd32_sigtimedwait_fetch_timeout(const void *src, void *dst, size_t size)
440 {
441 struct timespec *ts = dst;
442 struct netbsd32_timespec ts32;
443 int error;
444
445 error = copyin(src, &ts32, sizeof(ts32));
446 if (error)
447 return error;
448
449 netbsd32_to_timespec(&ts32, ts);
450 return 0;
451 }
452
453 static int
454 netbsd32_sigtimedwait_put_timeout(const void *src, void *dst, size_t size)
455 {
456 const struct timespec *ts = src;
457 struct netbsd32_timespec ts32;
458
459 netbsd32_from_timespec(ts, &ts32);
460
461 return copyout(&ts32, dst, sizeof(ts32));
462 }
463
464 int
465 netbsd32_____sigtimedwait50(struct lwp *l, const struct netbsd32_____sigtimedwait50_args *uap, register_t *retval)
466 {
467 /* {
468 syscallarg(netbsd32_sigsetp_t) set;
469 syscallarg(netbsd32_siginfop_t) info;
470 syscallarg(netbsd32_timespec50p_t) timeout;
471 } */
472 struct sys_____sigtimedwait50_args ua;
473
474 NETBSD32TOP_UAP(set, const sigset_t);
475 NETBSD32TOP_UAP(info, siginfo_t);
476 NETBSD32TOP_UAP(timeout, struct timespec);
477
478 return sigtimedwait1(l, &ua, retval,
479 copyin,
480 netbsd32_sigtimedwait_put_info,
481 netbsd32_sigtimedwait_fetch_timeout,
482 netbsd32_sigtimedwait_put_timeout);
483 }
484
485 int
486 netbsd32_sigqueueinfo(struct lwp *l,
487 const struct netbsd32_sigqueueinfo_args *uap, register_t *retval)
488 {
489 /* {
490 syscallarg(pid_t) pid;
491 syscallarg(const netbsd32_siginfop_t) info;
492 } */
493 struct __ksiginfo32 ksi32;
494 ksiginfo_t ksi;
495 int error;
496
497 if ((error = copyin(SCARG_P32(uap, info), &ksi32,
498 sizeof(ksi32))) != 0)
499 return error;
500
501 KSI_INIT(&ksi);
502 netbsd32_ksi32_to_ksi(&ksi.ksi_info, &ksi32);
503
504 return kill1(l, SCARG(uap, pid), &ksi, retval);
505 }
506
507 struct netbsd32_ktr_psig {
508 int signo;
509 netbsd32_pointer_t action;
510 sigset_t mask;
511 int code;
512 /* and optional siginfo_t */
513 };
514
515 #ifdef KTRACE
516 void
517 netbsd32_ktrpsig(int sig, sig_t action, const sigset_t *mask,
518 const ksiginfo_t *ksi)
519 {
520 struct ktrace_entry *kte;
521 lwp_t *l = curlwp;
522 struct {
523 struct netbsd32_ktr_psig kp;
524 siginfo32_t si;
525 } *kbuf;
526
527 if (!KTRPOINT(l->l_proc, KTR_PSIG))
528 return;
529
530 if (ktealloc(&kte, (void *)&kbuf, l, KTR_PSIG, sizeof(*kbuf)))
531 return;
532
533 kbuf->kp.signo = (char)sig;
534 NETBSD32PTR32(kbuf->kp.action, action);
535 kbuf->kp.mask = *mask;
536
537 if (ksi) {
538 kbuf->kp.code = KSI_TRAPCODE(ksi);
539 (void)memset(&kbuf->si, 0, sizeof(kbuf->si));
540 netbsd32_ksi_to_ksi32(&kbuf->si._info, &ksi->ksi_info);
541 ktesethdrlen(kte, sizeof(*kbuf));
542 } else {
543 kbuf->kp.code = 0;
544 ktesethdrlen(kte, sizeof(struct netbsd32_ktr_psig));
545 }
546
547 ktraddentry(l, kte, KTA_WAITOK);
548 }
549 #endif
550
551
552