1 /* $NetBSD: kern_sig_13.c,v 1.21 2019/01/27 02:08:39 pgoyette Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Charles M. Hannum. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: kern_sig_13.c,v 1.21 2019/01/27 02:08:39 pgoyette Exp $"); 34 35 #if defined(_KERNEL_OPT) 36 #include "opt_compat_netbsd.h" 37 #endif 38 39 #include <sys/param.h> 40 #include <sys/proc.h> 41 #include <sys/signal.h> 42 #include <sys/signalvar.h> 43 #include <sys/systm.h> 44 45 #include <sys/syscall.h> 46 #include <sys/syscallvar.h> 47 #include <sys/syscallargs.h> 48 49 #include <machine/limits.h> 50 51 #include <compat/sys/signal.h> 52 #include <compat/sys/signalvar.h> 53 #include <compat/common/compat_util.h> 54 #include <compat/common/compat_sigaltstack.h> 55 #include <compat/common/compat_mod.h> 56 57 static const struct syscall_package kern_sig_13_syscalls[] = { 58 { SYS_compat_13_sigaction13, 0, (sy_call_t *)compat_13_sys_sigaction }, 59 { SYS_compat_13_sigaltstack13, 0, 60 (sy_call_t *)compat_13_sys_sigaltstack }, 61 { SYS_compat_13_sigpending13, 0, 62 (sy_call_t *)compat_13_sys_sigpending }, 63 { SYS_compat_13_sigprocmask13, 0, 64 (sy_call_t *)compat_13_sys_sigprocmask }, 65 { SYS_compat_13_sigsuspend13, 0, 66 (sy_call_t *)compat_13_sys_sigsuspend }, 67 /* compat_13_sigreturn13 is in MD code! */ 68 { SYS_compat_13_sigreturn13, 0, (sy_call_t *)compat_13_sys_sigreturn }, 69 { 0, 0, NULL } 70 }; 71 72 void 73 native_sigset13_to_sigset(const sigset13_t *oss, sigset_t *ss) 74 { 75 76 ss->__bits[0] = *oss; 77 ss->__bits[1] = 0; 78 ss->__bits[2] = 0; 79 ss->__bits[3] = 0; 80 } 81 82 void 83 native_sigset_to_sigset13(const sigset_t *ss, sigset13_t *oss) 84 { 85 86 *oss = ss->__bits[0]; 87 } 88 89 void 90 native_sigaction13_to_sigaction(const struct sigaction13 *osa, struct sigaction *sa) 91 { 92 93 sa->sa_handler = osa->osa_handler; 94 native_sigset13_to_sigset(&osa->osa_mask, &sa->sa_mask); 95 sa->sa_flags = osa->osa_flags; 96 } 97 98 void 99 native_sigaction_to_sigaction13(const struct sigaction *sa, struct sigaction13 *osa) 100 { 101 102 osa->osa_handler = sa->sa_handler; 103 native_sigset_to_sigset13(&sa->sa_mask, &osa->osa_mask); 104 osa->osa_flags = sa->sa_flags; 105 } 106 107 int 108 compat_13_sys_sigaltstack(struct lwp *l, const struct compat_13_sys_sigaltstack_args *uap, register_t *retval) 109 { 110 /* { 111 syscallarg(const struct sigaltstack13 *) nss; 112 syscallarg(struct sigaltstack13 *) oss; 113 } */ 114 compat_sigaltstack(uap, sigaltstack13, SS_ONSTACK, SS_DISABLE); 115 } 116 117 int 118 compat_13_sys_sigaction(struct lwp *l, const struct compat_13_sys_sigaction_args *uap, register_t *retval) 119 { 120 /* { 121 syscallarg(int) signum; 122 syscallarg(const struct sigaction13 *) nsa; 123 syscallarg(struct sigaction13 *) osa; 124 } */ 125 struct sigaction13 nesa, oesa; 126 struct sigaction nbsa, obsa; 127 int error; 128 129 if (SCARG(uap, nsa)) { 130 error = copyin(SCARG(uap, nsa), &nesa, sizeof(nesa)); 131 if (error) 132 return (error); 133 native_sigaction13_to_sigaction(&nesa, &nbsa); 134 } 135 error = sigaction1(l, SCARG(uap, signum), 136 SCARG(uap, nsa) ? &nbsa : 0, SCARG(uap, osa) ? &obsa : 0, 137 NULL, 0); 138 if (error) 139 return (error); 140 if (SCARG(uap, osa)) { 141 native_sigaction_to_sigaction13(&obsa, &oesa); 142 error = copyout(&oesa, SCARG(uap, osa), sizeof(oesa)); 143 if (error) 144 return (error); 145 } 146 return (0); 147 } 148 149 int 150 compat_13_sys_sigprocmask(struct lwp *l, const struct compat_13_sys_sigprocmask_args *uap, register_t *retval) 151 { 152 /* { 153 syscallarg(int) how; 154 syscallarg(int) mask; 155 } */ 156 struct proc *p = l->l_proc; 157 sigset13_t ness, oess; 158 sigset_t nbss, obss; 159 int error; 160 161 ness = SCARG(uap, mask); 162 native_sigset13_to_sigset(&ness, &nbss); 163 mutex_enter(p->p_lock); 164 error = sigprocmask1(l, SCARG(uap, how), &nbss, &obss); 165 mutex_exit(p->p_lock); 166 if (error) 167 return (error); 168 native_sigset_to_sigset13(&obss, &oess); 169 *retval = oess; 170 return (0); 171 } 172 173 int 174 compat_13_sys_sigpending(struct lwp *l, const void *v, register_t *retval) 175 { 176 sigset13_t ess; 177 sigset_t bss; 178 179 sigpending1(l, &bss); 180 native_sigset_to_sigset13(&bss, &ess); 181 *retval = ess; 182 return (0); 183 } 184 185 int 186 compat_13_sys_sigsuspend(struct lwp *l, const struct compat_13_sys_sigsuspend_args *uap, register_t *retval) 187 { 188 /* { 189 syscallarg(sigset13_t) mask; 190 } */ 191 sigset13_t ess; 192 sigset_t bss; 193 194 ess = SCARG(uap, mask); 195 native_sigset13_to_sigset(&ess, &bss); 196 return (sigsuspend1(l, &bss)); 197 } 198 199 int 200 kern_sig_13_init(void) 201 { 202 203 return syscall_establish(NULL, kern_sig_13_syscalls); 204 } 205 206 int 207 kern_sig_13_fini(void) 208 { 209 210 return syscall_disestablish(NULL, kern_sig_13_syscalls); 211 } 212