1 /* $NetBSD: compat_16_machdep.c,v 1.2 2021/10/27 04:15:00 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1996, 1997, 1998, 2002 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 and by Jason R. Thorpe of the Numerical Aerospace 9 * Simulation Facility, NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /*- 34 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 35 * All rights reserved. 36 * 37 * This code is derived from software contributed to Berkeley by 38 * William Jolitz. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 3. Neither the name of the University nor the names of its contributors 49 * may be used to endorse or promote products derived from this software 50 * without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * SUCH DAMAGE. 63 * 64 * @(#)machdep.c 7.4 (Berkeley) 6/3/91 65 */ 66 67 #include <sys/cdefs.h> 68 __KERNEL_RCSID(0, "$NetBSD: compat_16_machdep.c,v 1.2 2021/10/27 04:15:00 thorpej Exp $"); 69 70 #ifdef _KERNEL_OPT 71 #include "opt_compat_netbsd.h" 72 #endif 73 74 #include <sys/param.h> 75 #include <sys/systm.h> 76 #include <sys/proc.h> 77 #include <sys/signal.h> 78 #include <sys/signalvar.h> 79 #include <sys/syscallargs.h> 80 #include <compat/sys/signal.h> 81 #include <compat/sys/signalvar.h> 82 83 84 #ifdef COMPAT_16 85 /* 86 * Stack is set up to allow sigcode stored 87 * in u. to call routine, followed by kcall 88 * to sigreturn routine below. After sigreturn 89 * resets the signal mask, the stack, and the 90 * frame pointer, it returns to the user 91 * specified pc, psl. 92 */ 93 void 94 sendsig_sigcontext(const ksiginfo_t *ksi, const sigset_t *mask) 95 { 96 struct lwp *l = curlwp; 97 struct proc *p = l->l_proc; 98 struct sigacts *ps = p->p_sigacts; 99 struct trapframe *tf = l->l_md.md_regs; 100 int sig = ksi->ksi_info._signo; 101 sig_t catcher = SIGACTION(p, sig).sa_handler; 102 struct sigframe_sigcontext *fp, frame; 103 int onstack, error; 104 105 fp = getframe(l, sig, &onstack); 106 --fp; 107 108 /* Save register context. */ 109 frame.sf_sc.sc_ssr = tf->tf_ssr; 110 frame.sf_sc.sc_spc = tf->tf_spc; 111 frame.sf_sc.sc_pr = tf->tf_pr; 112 frame.sf_sc.sc_r15 = tf->tf_r15; 113 frame.sf_sc.sc_r14 = tf->tf_r14; 114 frame.sf_sc.sc_r13 = tf->tf_r13; 115 frame.sf_sc.sc_r12 = tf->tf_r12; 116 frame.sf_sc.sc_r11 = tf->tf_r11; 117 frame.sf_sc.sc_r10 = tf->tf_r10; 118 frame.sf_sc.sc_r9 = tf->tf_r9; 119 frame.sf_sc.sc_r8 = tf->tf_r8; 120 frame.sf_sc.sc_r7 = tf->tf_r7; 121 frame.sf_sc.sc_r6 = tf->tf_r6; 122 frame.sf_sc.sc_r5 = tf->tf_r5; 123 frame.sf_sc.sc_r4 = tf->tf_r4; 124 frame.sf_sc.sc_r3 = tf->tf_r3; 125 frame.sf_sc.sc_r2 = tf->tf_r2; 126 frame.sf_sc.sc_r1 = tf->tf_r1; 127 frame.sf_sc.sc_r0 = tf->tf_r0; 128 frame.sf_sc.sc_expevt = tf->tf_expevt; 129 130 /* Save signal stack. */ 131 frame.sf_sc.sc_onstack = l->l_sigstk.ss_flags & SS_ONSTACK; 132 133 /* Save signal mask. */ 134 frame.sf_sc.sc_mask = *mask; 135 136 sendsig_reset(l, sig); 137 138 mutex_exit(p->p_lock); 139 error = copyout(&frame, fp, sizeof(frame)); 140 mutex_enter(p->p_lock); 141 142 if (error != 0) { 143 /* 144 * Process has trashed its stack; give it an illegal 145 * instruction to halt it in its tracks. 146 */ 147 sigexit(l, SIGILL); 148 /* NOTREACHED */ 149 } 150 151 /* 152 * Build context to run handler in. We invoke the handler 153 * directly, only returning via the trampoline. 154 */ 155 switch (ps->sa_sigdesc[sig].sd_vers) { 156 case __SIGTRAMP_SIGCODE_VERSION: /* legacy on-stack sigtramp */ 157 tf->tf_pr = (int)p->p_sigctx.ps_sigcode; 158 break; 159 160 case __SIGTRAMP_SIGCONTEXT_VERSION: 161 tf->tf_pr = (int)ps->sa_sigdesc[sig].sd_tramp; 162 break; 163 164 default: 165 /* Don't know what trampoline version; kill it. */ 166 printf("sendsig_sigcontext: bad version %d\n", 167 ps->sa_sigdesc[sig].sd_vers); 168 sigexit(l, SIGILL); 169 } 170 171 tf->tf_r4 = sig; 172 tf->tf_r5 = ksi->ksi_code; 173 tf->tf_r6 = (int)&fp->sf_sc; 174 tf->tf_spc = (int)catcher; 175 tf->tf_r15 = (int)fp; 176 177 /* Remember if we're now on the signal stack. */ 178 if (onstack) 179 l->l_sigstk.ss_flags |= SS_ONSTACK; 180 } 181 182 /* 183 * System call to cleanup state after a signal 184 * has been taken. Reset signal mask and 185 * stack state from context left by sendsig (above). 186 * Return to previous pc and psl as specified by 187 * context left by sendsig. Check carefully to 188 * make sure that the user has not modified the 189 * psl to gain improper privileges or to cause 190 * a machine fault. 191 */ 192 int 193 compat_16_sys___sigreturn14(struct lwp *l, const struct compat_16_sys___sigreturn14_args *uap, register_t *retval) 194 { 195 /* { 196 syscallarg(struct sigcontext *) sigcntxp; 197 } */ 198 struct sigcontext *scp, context; 199 struct trapframe *tf; 200 struct proc *p = l->l_proc; 201 202 /* 203 * The trampoline code hands us the context. 204 * It is unsafe to keep track of it ourselves, in the event that a 205 * program jumps out of a signal handler. 206 */ 207 scp = SCARG(uap, sigcntxp); 208 if (copyin((void *)scp, &context, sizeof(*scp)) != 0) 209 return (EFAULT); 210 211 /* Restore signal context. */ 212 tf = l->l_md.md_regs; 213 214 /* Check for security violations. */ 215 if (((context.sc_ssr ^ tf->tf_ssr) & PSL_USERSTATIC) != 0) 216 return (EINVAL); 217 218 tf->tf_ssr = context.sc_ssr; 219 220 tf->tf_r0 = context.sc_r0; 221 tf->tf_r1 = context.sc_r1; 222 tf->tf_r2 = context.sc_r2; 223 tf->tf_r3 = context.sc_r3; 224 tf->tf_r4 = context.sc_r4; 225 tf->tf_r5 = context.sc_r5; 226 tf->tf_r6 = context.sc_r6; 227 tf->tf_r7 = context.sc_r7; 228 tf->tf_r8 = context.sc_r8; 229 tf->tf_r9 = context.sc_r9; 230 tf->tf_r10 = context.sc_r10; 231 tf->tf_r11 = context.sc_r11; 232 tf->tf_r12 = context.sc_r12; 233 tf->tf_r13 = context.sc_r13; 234 tf->tf_r14 = context.sc_r14; 235 tf->tf_spc = context.sc_spc; 236 tf->tf_r15 = context.sc_r15; 237 tf->tf_pr = context.sc_pr; 238 239 mutex_enter(p->p_lock); 240 /* Restore signal stack. */ 241 if (context.sc_onstack & SS_ONSTACK) 242 l->l_sigstk.ss_flags |= SS_ONSTACK; 243 else 244 l->l_sigstk.ss_flags &= ~SS_ONSTACK; 245 /* Restore signal mask. */ 246 (void) sigprocmask1(l, SIG_SETMASK, &context.sc_mask, 0); 247 mutex_exit(p->p_lock); 248 249 return (EJUSTRETURN); 250 } 251 #endif /* COMPAT_16 */ 252