1/*- 2 * Copyright (c) 1994-1996 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 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 withough 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 *
| 1/*- 2 * Copyright (c) 1994-1996 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 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 withough 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 * $FreeBSD: head/sys/i386/linux/linux_sysvec.c 71039 2001-01-14 18:16:01Z des $
| 28 * $FreeBSD: head/sys/i386/linux/linux_sysvec.c 71497 2001-01-24 00:27:28Z jhb $
|
29 */ 30 31/* XXX we use functions that might not exist. */ 32#include "opt_compat.h" 33 34#ifndef COMPAT_43 35#error "Unable to compile Linux-emulator due to missing COMPAT_43 option!" 36#endif 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/proc.h> 41#include <sys/sysproto.h> 42#include <sys/sysent.h> 43#include <sys/imgact.h> 44#include <sys/imgact_aout.h> 45#include <sys/imgact_elf.h> 46#include <sys/signalvar.h> 47#include <sys/malloc.h> 48#include <vm/vm.h> 49#include <vm/vm_param.h> 50#include <vm/vm_page.h> 51#include <vm/vm_extern.h> 52#include <sys/exec.h> 53#include <sys/kernel.h> 54#include <sys/module.h> 55#include <machine/cpu.h> 56 57#include <i386/linux/linux.h> 58#include <i386/linux/linux_proto.h> 59#include <compat/linux/linux_signal.h> 60#include <compat/linux/linux_util.h> 61 62MODULE_VERSION(linux, 1); 63MODULE_DEPEND(linux, sysvmsg, 1, 1, 1); 64MODULE_DEPEND(linux, sysvsem, 1, 1, 1); 65MODULE_DEPEND(linux, sysvshm, 1, 1, 1); 66 67MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures"); 68 69#if BYTE_ORDER == LITTLE_ENDIAN 70#define SHELLMAGIC 0x2123 /* #! */ 71#else 72#define SHELLMAGIC 0x2321 73#endif 74 75extern char linux_sigcode[]; 76extern int linux_szsigcode; 77 78extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; 79 80extern struct linker_set linux_ioctl_handler_set; 81 82static int linux_fixup __P((register_t **stack_base, 83 struct image_params *iparams)); 84static int elf_linux_fixup __P((register_t **stack_base, 85 struct image_params *iparams)); 86static void linux_prepsyscall __P((struct trapframe *tf, int *args, 87 u_int *code, caddr_t *params)); 88static void linux_sendsig __P((sig_t catcher, int sig, sigset_t *mask, 89 u_long code)); 90 91/* 92 * Linux syscalls return negative errno's, we do positive and map them 93 */ 94static int bsd_to_linux_errno[ELAST + 1] = { 95 -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, 96 -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, 97 -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, 98 -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, 99 -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, 100 -100,-101,-102,-103,-104,-105,-106,-107,-108,-109, 101 -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, 102 -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, 103 -6, -6, -43, -42, -75, -6, -84 104}; 105 106int bsd_to_linux_signal[LINUX_SIGTBLSZ] = { 107 LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL, 108 LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE, 109 LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, 0, 110 LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG, 111 LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD, 112 LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU, 113 LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH, 114 0, LINUX_SIGUSR1, LINUX_SIGUSR2 115}; 116 117int linux_to_bsd_signal[LINUX_SIGTBLSZ] = { 118 SIGHUP, SIGINT, SIGQUIT, SIGILL, 119 SIGTRAP, SIGABRT, SIGBUS, SIGFPE, 120 SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, 121 SIGPIPE, SIGALRM, SIGTERM, SIGBUS, 122 SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, 123 SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, 124 SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, 125 SIGIO, SIGURG, 0 126}; 127 128/* 129 * If FreeBSD & Linux have a difference of opinion about what a trap 130 * means, deal with it here. 131 */ 132static int 133translate_traps(int signal, int trap_code) 134{ 135 if (signal != SIGBUS) 136 return signal; 137 switch (trap_code) { 138 case T_PROTFLT: 139 case T_TSSFLT: 140 case T_DOUBLEFLT: 141 case T_PAGEFLT: 142 return SIGSEGV; 143 default: 144 return signal; 145 } 146} 147 148static int 149linux_fixup(register_t **stack_base, struct image_params *imgp) 150{ 151 register_t *argv, *envp; 152 153 argv = *stack_base; 154 envp = *stack_base + (imgp->argc + 1); 155 (*stack_base)--; 156 **stack_base = (intptr_t)(void *)envp; 157 (*stack_base)--; 158 **stack_base = (intptr_t)(void *)argv; 159 (*stack_base)--; 160 **stack_base = imgp->argc; 161 return 0; 162} 163 164static int 165elf_linux_fixup(register_t **stack_base, struct image_params *imgp) 166{ 167 Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs; 168 register_t *pos; 169 170 pos = *stack_base + (imgp->argc + imgp->envc + 2); 171 172 if (args->trace) { 173 AUXARGS_ENTRY(pos, AT_DEBUG, 1); 174 } 175 if (args->execfd != -1) { 176 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); 177 } 178 AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); 179 AUXARGS_ENTRY(pos, AT_PHENT, args->phent); 180 AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); 181 AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz); 182 AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); 183 AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); 184 AUXARGS_ENTRY(pos, AT_BASE, args->base);
| 29 */ 30 31/* XXX we use functions that might not exist. */ 32#include "opt_compat.h" 33 34#ifndef COMPAT_43 35#error "Unable to compile Linux-emulator due to missing COMPAT_43 option!" 36#endif 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/proc.h> 41#include <sys/sysproto.h> 42#include <sys/sysent.h> 43#include <sys/imgact.h> 44#include <sys/imgact_aout.h> 45#include <sys/imgact_elf.h> 46#include <sys/signalvar.h> 47#include <sys/malloc.h> 48#include <vm/vm.h> 49#include <vm/vm_param.h> 50#include <vm/vm_page.h> 51#include <vm/vm_extern.h> 52#include <sys/exec.h> 53#include <sys/kernel.h> 54#include <sys/module.h> 55#include <machine/cpu.h> 56 57#include <i386/linux/linux.h> 58#include <i386/linux/linux_proto.h> 59#include <compat/linux/linux_signal.h> 60#include <compat/linux/linux_util.h> 61 62MODULE_VERSION(linux, 1); 63MODULE_DEPEND(linux, sysvmsg, 1, 1, 1); 64MODULE_DEPEND(linux, sysvsem, 1, 1, 1); 65MODULE_DEPEND(linux, sysvshm, 1, 1, 1); 66 67MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures"); 68 69#if BYTE_ORDER == LITTLE_ENDIAN 70#define SHELLMAGIC 0x2123 /* #! */ 71#else 72#define SHELLMAGIC 0x2321 73#endif 74 75extern char linux_sigcode[]; 76extern int linux_szsigcode; 77 78extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; 79 80extern struct linker_set linux_ioctl_handler_set; 81 82static int linux_fixup __P((register_t **stack_base, 83 struct image_params *iparams)); 84static int elf_linux_fixup __P((register_t **stack_base, 85 struct image_params *iparams)); 86static void linux_prepsyscall __P((struct trapframe *tf, int *args, 87 u_int *code, caddr_t *params)); 88static void linux_sendsig __P((sig_t catcher, int sig, sigset_t *mask, 89 u_long code)); 90 91/* 92 * Linux syscalls return negative errno's, we do positive and map them 93 */ 94static int bsd_to_linux_errno[ELAST + 1] = { 95 -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, 96 -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, 97 -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, 98 -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, 99 -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, 100 -100,-101,-102,-103,-104,-105,-106,-107,-108,-109, 101 -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, 102 -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, 103 -6, -6, -43, -42, -75, -6, -84 104}; 105 106int bsd_to_linux_signal[LINUX_SIGTBLSZ] = { 107 LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL, 108 LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE, 109 LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, 0, 110 LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG, 111 LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD, 112 LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU, 113 LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH, 114 0, LINUX_SIGUSR1, LINUX_SIGUSR2 115}; 116 117int linux_to_bsd_signal[LINUX_SIGTBLSZ] = { 118 SIGHUP, SIGINT, SIGQUIT, SIGILL, 119 SIGTRAP, SIGABRT, SIGBUS, SIGFPE, 120 SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, 121 SIGPIPE, SIGALRM, SIGTERM, SIGBUS, 122 SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, 123 SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, 124 SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, 125 SIGIO, SIGURG, 0 126}; 127 128/* 129 * If FreeBSD & Linux have a difference of opinion about what a trap 130 * means, deal with it here. 131 */ 132static int 133translate_traps(int signal, int trap_code) 134{ 135 if (signal != SIGBUS) 136 return signal; 137 switch (trap_code) { 138 case T_PROTFLT: 139 case T_TSSFLT: 140 case T_DOUBLEFLT: 141 case T_PAGEFLT: 142 return SIGSEGV; 143 default: 144 return signal; 145 } 146} 147 148static int 149linux_fixup(register_t **stack_base, struct image_params *imgp) 150{ 151 register_t *argv, *envp; 152 153 argv = *stack_base; 154 envp = *stack_base + (imgp->argc + 1); 155 (*stack_base)--; 156 **stack_base = (intptr_t)(void *)envp; 157 (*stack_base)--; 158 **stack_base = (intptr_t)(void *)argv; 159 (*stack_base)--; 160 **stack_base = imgp->argc; 161 return 0; 162} 163 164static int 165elf_linux_fixup(register_t **stack_base, struct image_params *imgp) 166{ 167 Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs; 168 register_t *pos; 169 170 pos = *stack_base + (imgp->argc + imgp->envc + 2); 171 172 if (args->trace) { 173 AUXARGS_ENTRY(pos, AT_DEBUG, 1); 174 } 175 if (args->execfd != -1) { 176 AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); 177 } 178 AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); 179 AUXARGS_ENTRY(pos, AT_PHENT, args->phent); 180 AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); 181 AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz); 182 AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); 183 AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); 184 AUXARGS_ENTRY(pos, AT_BASE, args->base);
|
| 185 PROC_LOCK(imgp->proc);
|
185 AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_cred->p_ruid); 186 AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_cred->p_svuid); 187 AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_cred->p_rgid); 188 AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_cred->p_svgid);
| 186 AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_cred->p_ruid); 187 AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_cred->p_svuid); 188 AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_cred->p_rgid); 189 AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_cred->p_svgid);
|
| 190 PROC_UNLOCK(imgp->proc);
|
189 AUXARGS_ENTRY(pos, AT_NULL, 0); 190 191 free(imgp->auxargs, M_TEMP); 192 imgp->auxargs = NULL; 193 194 (*stack_base)--; 195 **stack_base = (long)imgp->argc; 196 return 0; 197} 198 199extern int _ucodesel, _udatasel; 200extern unsigned long _linux_sznonrtsigcode; 201 202static void 203linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 204{ 205 register struct proc *p = curproc; 206 register struct trapframe *regs; 207 struct linux_rt_sigframe *fp, frame; 208 int oonstack; 209 210 regs = p->p_md.md_regs; 211 oonstack = sigonstack(regs->tf_esp); 212 213#ifdef DEBUG 214 printf("Linux-emul(%ld): linux_rt_sendsig(%p, %d, %p, %lu)\n", 215 (long)p->p_pid, catcher, sig, (void*)mask, code); 216#endif 217 /* 218 * Allocate space for the signal handler context. 219 */
| 191 AUXARGS_ENTRY(pos, AT_NULL, 0); 192 193 free(imgp->auxargs, M_TEMP); 194 imgp->auxargs = NULL; 195 196 (*stack_base)--; 197 **stack_base = (long)imgp->argc; 198 return 0; 199} 200 201extern int _ucodesel, _udatasel; 202extern unsigned long _linux_sznonrtsigcode; 203 204static void 205linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 206{ 207 register struct proc *p = curproc; 208 register struct trapframe *regs; 209 struct linux_rt_sigframe *fp, frame; 210 int oonstack; 211 212 regs = p->p_md.md_regs; 213 oonstack = sigonstack(regs->tf_esp); 214 215#ifdef DEBUG 216 printf("Linux-emul(%ld): linux_rt_sendsig(%p, %d, %p, %lu)\n", 217 (long)p->p_pid, catcher, sig, (void*)mask, code); 218#endif 219 /* 220 * Allocate space for the signal handler context. 221 */
|
| 222 PROC_LOCK(p);
|
220 if ((p->p_flag & P_ALTSTACK) && !oonstack && 221 SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) { 222 fp = (struct linux_rt_sigframe *)(p->p_sigstk.ss_sp + 223 p->p_sigstk.ss_size - sizeof(struct linux_rt_sigframe)); 224 } else 225 fp = (struct linux_rt_sigframe *)regs->tf_esp - 1;
| 223 if ((p->p_flag & P_ALTSTACK) && !oonstack && 224 SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) { 225 fp = (struct linux_rt_sigframe *)(p->p_sigstk.ss_sp + 226 p->p_sigstk.ss_size - sizeof(struct linux_rt_sigframe)); 227 } else 228 fp = (struct linux_rt_sigframe *)regs->tf_esp - 1;
|
| 229 PROC_UNLOCK(p);
|
226 227 /* 228 * grow() will return FALSE if the fp will not fit inside the stack 229 * and the stack can not be grown. useracc will return FALSE 230 * if access is denied. 231 */ 232 if ((grow_stack (p, (int)fp) == FALSE) || 233 !useracc((caddr_t)fp, sizeof (struct linux_rt_sigframe), 234 VM_PROT_WRITE)) { 235 /* 236 * Process has trashed its stack; give it an illegal 237 * instruction to halt it in its tracks. 238 */
| 230 231 /* 232 * grow() will return FALSE if the fp will not fit inside the stack 233 * and the stack can not be grown. useracc will return FALSE 234 * if access is denied. 235 */ 236 if ((grow_stack (p, (int)fp) == FALSE) || 237 !useracc((caddr_t)fp, sizeof (struct linux_rt_sigframe), 238 VM_PROT_WRITE)) { 239 /* 240 * Process has trashed its stack; give it an illegal 241 * instruction to halt it in its tracks. 242 */
|
| 243 PROC_LOCK(p);
|
239 SIGACTION(p, SIGILL) = SIG_DFL; 240 SIGDELSET(p->p_sigignore, SIGILL); 241 SIGDELSET(p->p_sigcatch, SIGILL); 242 SIGDELSET(p->p_sigmask, SIGILL);
| 244 SIGACTION(p, SIGILL) = SIG_DFL; 245 SIGDELSET(p->p_sigignore, SIGILL); 246 SIGDELSET(p->p_sigcatch, SIGILL); 247 SIGDELSET(p->p_sigmask, SIGILL);
|
| 248 PROC_UNLOCK(p);
|
243#ifdef DEBUG 244 printf("Linux-emul(%ld): linux_rt_sendsig -- bad stack %p, " 245 "oonstack=%x\n", (long)p->p_pid, fp, oonstack); 246#endif 247 psignal(p, SIGILL); 248 return; 249 } 250 251 /* 252 * Build the argument list for the signal handler. 253 */ 254 if (p->p_sysent->sv_sigtbl) 255 if (sig <= p->p_sysent->sv_sigsize) 256 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 257 258 frame.sf_handler = catcher; 259 frame.sf_sig = sig; 260 frame.sf_siginfo = &fp->sf_si; 261 frame.sf_ucontext = &fp->sf_sc; 262 263 /* Fill siginfo structure. */ 264 frame.sf_si.lsi_signo = sig; 265 frame.sf_si.lsi_code = code; 266 frame.sf_si.lsi_addr = (void *)regs->tf_err; 267 268 /* 269 * Build the signal context to be used by sigreturn. 270 */ 271 frame.sf_sc.uc_flags = 0; /* XXX ??? */ 272 frame.sf_sc.uc_link = NULL; /* XXX ??? */ 273
| 249#ifdef DEBUG 250 printf("Linux-emul(%ld): linux_rt_sendsig -- bad stack %p, " 251 "oonstack=%x\n", (long)p->p_pid, fp, oonstack); 252#endif 253 psignal(p, SIGILL); 254 return; 255 } 256 257 /* 258 * Build the argument list for the signal handler. 259 */ 260 if (p->p_sysent->sv_sigtbl) 261 if (sig <= p->p_sysent->sv_sigsize) 262 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 263 264 frame.sf_handler = catcher; 265 frame.sf_sig = sig; 266 frame.sf_siginfo = &fp->sf_si; 267 frame.sf_ucontext = &fp->sf_sc; 268 269 /* Fill siginfo structure. */ 270 frame.sf_si.lsi_signo = sig; 271 frame.sf_si.lsi_code = code; 272 frame.sf_si.lsi_addr = (void *)regs->tf_err; 273 274 /* 275 * Build the signal context to be used by sigreturn. 276 */ 277 frame.sf_sc.uc_flags = 0; /* XXX ??? */ 278 frame.sf_sc.uc_link = NULL; /* XXX ??? */ 279
|
| 280 PROC_LOCK(p);
|
274 frame.sf_sc.uc_stack.ss_sp = p->p_sigstk.ss_sp; 275 frame.sf_sc.uc_stack.ss_size = p->p_sigstk.ss_size; 276 frame.sf_sc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK) 277 ? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE;
| 281 frame.sf_sc.uc_stack.ss_sp = p->p_sigstk.ss_sp; 282 frame.sf_sc.uc_stack.ss_size = p->p_sigstk.ss_size; 283 frame.sf_sc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK) 284 ? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE;
|
| 285 PROC_UNLOCK(p);
|
278 279 bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask); 280 281 frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__bits[0]; 282 frame.sf_sc.uc_mcontext.sc_gs = rgs(); 283 frame.sf_sc.uc_mcontext.sc_fs = regs->tf_fs; 284 frame.sf_sc.uc_mcontext.sc_es = regs->tf_es; 285 frame.sf_sc.uc_mcontext.sc_ds = regs->tf_ds; 286 frame.sf_sc.uc_mcontext.sc_edi = regs->tf_edi; 287 frame.sf_sc.uc_mcontext.sc_esi = regs->tf_esi; 288 frame.sf_sc.uc_mcontext.sc_ebp = regs->tf_ebp; 289 frame.sf_sc.uc_mcontext.sc_ebx = regs->tf_ebx; 290 frame.sf_sc.uc_mcontext.sc_edx = regs->tf_edx; 291 frame.sf_sc.uc_mcontext.sc_ecx = regs->tf_ecx; 292 frame.sf_sc.uc_mcontext.sc_eax = regs->tf_eax; 293 frame.sf_sc.uc_mcontext.sc_eip = regs->tf_eip; 294 frame.sf_sc.uc_mcontext.sc_cs = regs->tf_cs; 295 frame.sf_sc.uc_mcontext.sc_eflags = regs->tf_eflags; 296 frame.sf_sc.uc_mcontext.sc_esp_at_signal = regs->tf_esp; 297 frame.sf_sc.uc_mcontext.sc_ss = regs->tf_ss; 298 frame.sf_sc.uc_mcontext.sc_err = regs->tf_err; 299 frame.sf_sc.uc_mcontext.sc_trapno = code; /* XXX ???? */ 300 301#ifdef DEBUG 302 printf("Linux-emul(%ld): rt_sendsig flags: 0x%x, sp: %p, ss: 0x%x, " 303 "mask: 0x%x\n", (long)p->p_pid, frame.sf_sc.uc_stack.ss_flags, 304 p->p_sigstk.ss_sp, p->p_sigstk.ss_size, 305 frame.sf_sc.uc_mcontext.sc_mask); 306#endif 307 308 if (copyout(&frame, fp, sizeof(frame)) != 0) { 309 /* 310 * Process has trashed its stack; give it an illegal 311 * instruction to halt it in its tracks. 312 */ 313 sigexit(p, SIGILL); 314 /* NOTREACHED */ 315 } 316 317 /* 318 * Build context to run handler in. 319 */ 320 regs->tf_esp = (int)fp; 321 regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode) + 322 _linux_sznonrtsigcode; 323 regs->tf_eflags &= ~PSL_VM; 324 regs->tf_cs = _ucodesel; 325 regs->tf_ds = _udatasel; 326 regs->tf_es = _udatasel; 327 regs->tf_fs = _udatasel; 328 load_gs(_udatasel); 329 regs->tf_ss = _udatasel; 330} 331 332 333/* 334 * Send an interrupt to process. 335 * 336 * Stack is set up to allow sigcode stored 337 * in u. to call routine, followed by kcall 338 * to sigreturn routine below. After sigreturn 339 * resets the signal mask, the stack, and the 340 * frame pointer, it returns to the user 341 * specified pc, psl. 342 */ 343 344static void 345linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 346{ 347 register struct proc *p = curproc; 348 register struct trapframe *regs; 349 struct linux_sigframe *fp, frame; 350 linux_sigset_t lmask; 351 int oonstack, i; 352 353 if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) { 354 /* Signal handler installed with SA_SIGINFO. */ 355 linux_rt_sendsig(catcher, sig, mask, code); 356 return; 357 } 358 359 regs = p->p_md.md_regs; 360 oonstack = sigonstack(regs->tf_esp); 361 362#ifdef DEBUG 363 printf("Linux-emul(%ld): linux_sendsig(%p, %d, %p, %lu)\n", 364 (long)p->p_pid, catcher, sig, (void*)mask, code); 365#endif 366 367 /* 368 * Allocate space for the signal handler context. 369 */
| 286 287 bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask); 288 289 frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__bits[0]; 290 frame.sf_sc.uc_mcontext.sc_gs = rgs(); 291 frame.sf_sc.uc_mcontext.sc_fs = regs->tf_fs; 292 frame.sf_sc.uc_mcontext.sc_es = regs->tf_es; 293 frame.sf_sc.uc_mcontext.sc_ds = regs->tf_ds; 294 frame.sf_sc.uc_mcontext.sc_edi = regs->tf_edi; 295 frame.sf_sc.uc_mcontext.sc_esi = regs->tf_esi; 296 frame.sf_sc.uc_mcontext.sc_ebp = regs->tf_ebp; 297 frame.sf_sc.uc_mcontext.sc_ebx = regs->tf_ebx; 298 frame.sf_sc.uc_mcontext.sc_edx = regs->tf_edx; 299 frame.sf_sc.uc_mcontext.sc_ecx = regs->tf_ecx; 300 frame.sf_sc.uc_mcontext.sc_eax = regs->tf_eax; 301 frame.sf_sc.uc_mcontext.sc_eip = regs->tf_eip; 302 frame.sf_sc.uc_mcontext.sc_cs = regs->tf_cs; 303 frame.sf_sc.uc_mcontext.sc_eflags = regs->tf_eflags; 304 frame.sf_sc.uc_mcontext.sc_esp_at_signal = regs->tf_esp; 305 frame.sf_sc.uc_mcontext.sc_ss = regs->tf_ss; 306 frame.sf_sc.uc_mcontext.sc_err = regs->tf_err; 307 frame.sf_sc.uc_mcontext.sc_trapno = code; /* XXX ???? */ 308 309#ifdef DEBUG 310 printf("Linux-emul(%ld): rt_sendsig flags: 0x%x, sp: %p, ss: 0x%x, " 311 "mask: 0x%x\n", (long)p->p_pid, frame.sf_sc.uc_stack.ss_flags, 312 p->p_sigstk.ss_sp, p->p_sigstk.ss_size, 313 frame.sf_sc.uc_mcontext.sc_mask); 314#endif 315 316 if (copyout(&frame, fp, sizeof(frame)) != 0) { 317 /* 318 * Process has trashed its stack; give it an illegal 319 * instruction to halt it in its tracks. 320 */ 321 sigexit(p, SIGILL); 322 /* NOTREACHED */ 323 } 324 325 /* 326 * Build context to run handler in. 327 */ 328 regs->tf_esp = (int)fp; 329 regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode) + 330 _linux_sznonrtsigcode; 331 regs->tf_eflags &= ~PSL_VM; 332 regs->tf_cs = _ucodesel; 333 regs->tf_ds = _udatasel; 334 regs->tf_es = _udatasel; 335 regs->tf_fs = _udatasel; 336 load_gs(_udatasel); 337 regs->tf_ss = _udatasel; 338} 339 340 341/* 342 * Send an interrupt to process. 343 * 344 * Stack is set up to allow sigcode stored 345 * in u. to call routine, followed by kcall 346 * to sigreturn routine below. After sigreturn 347 * resets the signal mask, the stack, and the 348 * frame pointer, it returns to the user 349 * specified pc, psl. 350 */ 351 352static void 353linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 354{ 355 register struct proc *p = curproc; 356 register struct trapframe *regs; 357 struct linux_sigframe *fp, frame; 358 linux_sigset_t lmask; 359 int oonstack, i; 360 361 if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) { 362 /* Signal handler installed with SA_SIGINFO. */ 363 linux_rt_sendsig(catcher, sig, mask, code); 364 return; 365 } 366 367 regs = p->p_md.md_regs; 368 oonstack = sigonstack(regs->tf_esp); 369 370#ifdef DEBUG 371 printf("Linux-emul(%ld): linux_sendsig(%p, %d, %p, %lu)\n", 372 (long)p->p_pid, catcher, sig, (void*)mask, code); 373#endif 374 375 /* 376 * Allocate space for the signal handler context. 377 */
|
| 378 PROC_LOCK(p);
|
370 if ((p->p_flag & P_ALTSTACK) && !oonstack && 371 SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) { 372 fp = (struct linux_sigframe *)(p->p_sigstk.ss_sp + 373 p->p_sigstk.ss_size - sizeof(struct linux_sigframe)); 374 } else 375 fp = (struct linux_sigframe *)regs->tf_esp - 1;
| 379 if ((p->p_flag & P_ALTSTACK) && !oonstack && 380 SIGISMEMBER(p->p_sigacts->ps_sigonstack, sig)) { 381 fp = (struct linux_sigframe *)(p->p_sigstk.ss_sp + 382 p->p_sigstk.ss_size - sizeof(struct linux_sigframe)); 383 } else 384 fp = (struct linux_sigframe *)regs->tf_esp - 1;
|
| 385 PROC_UNLOCK(p);
|
376 377 /* 378 * grow() will return FALSE if the fp will not fit inside the stack 379 * and the stack can not be grown. useracc will return FALSE 380 * if access is denied. 381 */ 382 if ((grow_stack (p, (int)fp) == FALSE) || 383 !useracc((caddr_t)fp, sizeof (struct linux_sigframe), 384 VM_PROT_WRITE)) { 385 /* 386 * Process has trashed its stack; give it an illegal 387 * instruction to halt it in its tracks. 388 */
| 386 387 /* 388 * grow() will return FALSE if the fp will not fit inside the stack 389 * and the stack can not be grown. useracc will return FALSE 390 * if access is denied. 391 */ 392 if ((grow_stack (p, (int)fp) == FALSE) || 393 !useracc((caddr_t)fp, sizeof (struct linux_sigframe), 394 VM_PROT_WRITE)) { 395 /* 396 * Process has trashed its stack; give it an illegal 397 * instruction to halt it in its tracks. 398 */
|
| 399 PROC_LOCK(p);
|
389 SIGACTION(p, SIGILL) = SIG_DFL; 390 SIGDELSET(p->p_sigignore, SIGILL); 391 SIGDELSET(p->p_sigcatch, SIGILL); 392 SIGDELSET(p->p_sigmask, SIGILL);
| 400 SIGACTION(p, SIGILL) = SIG_DFL; 401 SIGDELSET(p->p_sigignore, SIGILL); 402 SIGDELSET(p->p_sigcatch, SIGILL); 403 SIGDELSET(p->p_sigmask, SIGILL);
|
| 404 PROC_UNLOCK(p);
|
393 psignal(p, SIGILL); 394 return; 395 } 396 397 /* 398 * Build the argument list for the signal handler. 399 */ 400 if (p->p_sysent->sv_sigtbl) 401 if (sig <= p->p_sysent->sv_sigsize) 402 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 403 404 frame.sf_handler = catcher; 405 frame.sf_sig = sig; 406 407 bsd_to_linux_sigset(mask, &lmask); 408 409 /* 410 * Build the signal context to be used by sigreturn. 411 */ 412 frame.sf_sc.sc_mask = lmask.__bits[0]; 413 frame.sf_sc.sc_gs = rgs(); 414 frame.sf_sc.sc_fs = regs->tf_fs; 415 frame.sf_sc.sc_es = regs->tf_es; 416 frame.sf_sc.sc_ds = regs->tf_ds; 417 frame.sf_sc.sc_edi = regs->tf_edi; 418 frame.sf_sc.sc_esi = regs->tf_esi; 419 frame.sf_sc.sc_ebp = regs->tf_ebp; 420 frame.sf_sc.sc_ebx = regs->tf_ebx; 421 frame.sf_sc.sc_edx = regs->tf_edx; 422 frame.sf_sc.sc_ecx = regs->tf_ecx; 423 frame.sf_sc.sc_eax = regs->tf_eax; 424 frame.sf_sc.sc_eip = regs->tf_eip; 425 frame.sf_sc.sc_cs = regs->tf_cs; 426 frame.sf_sc.sc_eflags = regs->tf_eflags; 427 frame.sf_sc.sc_esp_at_signal = regs->tf_esp; 428 frame.sf_sc.sc_ss = regs->tf_ss; 429 frame.sf_sc.sc_err = regs->tf_err; 430 frame.sf_sc.sc_trapno = code; /* XXX ???? */ 431 432 bzero(&frame.sf_fpstate, sizeof(struct linux_fpstate)); 433 434 for (i = 0; i < (LINUX_NSIG_WORDS-1); i++) 435 frame.sf_extramask[i] = lmask.__bits[i+1]; 436 437 if (copyout(&frame, fp, sizeof(frame)) != 0) { 438 /* 439 * Process has trashed its stack; give it an illegal 440 * instruction to halt it in its tracks. 441 */ 442 sigexit(p, SIGILL); 443 /* NOTREACHED */ 444 } 445 446 /* 447 * Build context to run handler in. 448 */ 449 regs->tf_esp = (int)fp; 450 regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode); 451 regs->tf_eflags &= ~PSL_VM; 452 regs->tf_cs = _ucodesel; 453 regs->tf_ds = _udatasel; 454 regs->tf_es = _udatasel; 455 regs->tf_fs = _udatasel; 456 load_gs(_udatasel); 457 regs->tf_ss = _udatasel; 458} 459 460/* 461 * System call to cleanup state after a signal 462 * has been taken. Reset signal mask and 463 * stack state from context left by sendsig (above). 464 * Return to previous pc and psl as specified by 465 * context left by sendsig. Check carefully to 466 * make sure that the user has not modified the 467 * psl to gain improper privileges or to cause 468 * a machine fault. 469 */ 470int 471linux_sigreturn(p, args) 472 struct proc *p; 473 struct linux_sigreturn_args *args; 474{ 475 struct linux_sigframe frame; 476 register struct trapframe *regs; 477 linux_sigset_t lmask; 478 int eflags, i; 479 480 regs = p->p_md.md_regs; 481 482#ifdef DEBUG 483 printf("Linux-emul(%ld): linux_sigreturn(%p)\n", 484 (long)p->p_pid, (void *)args->sfp); 485#endif 486 /* 487 * The trampoline code hands us the sigframe. 488 * It is unsafe to keep track of it ourselves, in the event that a 489 * program jumps out of a signal handler. 490 */ 491 if (copyin((caddr_t)args->sfp, &frame, sizeof(frame)) != 0) 492 return (EFAULT); 493 494 /* 495 * Check for security violations. 496 */ 497#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) 498 eflags = frame.sf_sc.sc_eflags; 499 /* 500 * XXX do allow users to change the privileged flag PSL_RF. The 501 * cpu sets PSL_RF in tf_eflags for faults. Debuggers should 502 * sometimes set it there too. tf_eflags is kept in the signal 503 * context during signal handling and there is no other place 504 * to remember it, so the PSL_RF bit may be corrupted by the 505 * signal handler without us knowing. Corruption of the PSL_RF 506 * bit at worst causes one more or one less debugger trap, so 507 * allowing it is fairly harmless. 508 */ 509 if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) { 510 return(EINVAL); 511 } 512 513 /* 514 * Don't allow users to load a valid privileged %cs. Let the 515 * hardware check for invalid selectors, excess privilege in 516 * other selectors, invalid %eip's and invalid %esp's. 517 */ 518#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) 519 if (!CS_SECURE(frame.sf_sc.sc_cs)) { 520 trapsignal(p, SIGBUS, T_PROTFLT); 521 return(EINVAL); 522 } 523 524 lmask.__bits[0] = frame.sf_sc.sc_mask; 525 for (i = 0; i < (LINUX_NSIG_WORDS-1); i++) 526 lmask.__bits[i+1] = frame.sf_extramask[i];
| 405 psignal(p, SIGILL); 406 return; 407 } 408 409 /* 410 * Build the argument list for the signal handler. 411 */ 412 if (p->p_sysent->sv_sigtbl) 413 if (sig <= p->p_sysent->sv_sigsize) 414 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 415 416 frame.sf_handler = catcher; 417 frame.sf_sig = sig; 418 419 bsd_to_linux_sigset(mask, &lmask); 420 421 /* 422 * Build the signal context to be used by sigreturn. 423 */ 424 frame.sf_sc.sc_mask = lmask.__bits[0]; 425 frame.sf_sc.sc_gs = rgs(); 426 frame.sf_sc.sc_fs = regs->tf_fs; 427 frame.sf_sc.sc_es = regs->tf_es; 428 frame.sf_sc.sc_ds = regs->tf_ds; 429 frame.sf_sc.sc_edi = regs->tf_edi; 430 frame.sf_sc.sc_esi = regs->tf_esi; 431 frame.sf_sc.sc_ebp = regs->tf_ebp; 432 frame.sf_sc.sc_ebx = regs->tf_ebx; 433 frame.sf_sc.sc_edx = regs->tf_edx; 434 frame.sf_sc.sc_ecx = regs->tf_ecx; 435 frame.sf_sc.sc_eax = regs->tf_eax; 436 frame.sf_sc.sc_eip = regs->tf_eip; 437 frame.sf_sc.sc_cs = regs->tf_cs; 438 frame.sf_sc.sc_eflags = regs->tf_eflags; 439 frame.sf_sc.sc_esp_at_signal = regs->tf_esp; 440 frame.sf_sc.sc_ss = regs->tf_ss; 441 frame.sf_sc.sc_err = regs->tf_err; 442 frame.sf_sc.sc_trapno = code; /* XXX ???? */ 443 444 bzero(&frame.sf_fpstate, sizeof(struct linux_fpstate)); 445 446 for (i = 0; i < (LINUX_NSIG_WORDS-1); i++) 447 frame.sf_extramask[i] = lmask.__bits[i+1]; 448 449 if (copyout(&frame, fp, sizeof(frame)) != 0) { 450 /* 451 * Process has trashed its stack; give it an illegal 452 * instruction to halt it in its tracks. 453 */ 454 sigexit(p, SIGILL); 455 /* NOTREACHED */ 456 } 457 458 /* 459 * Build context to run handler in. 460 */ 461 regs->tf_esp = (int)fp; 462 regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode); 463 regs->tf_eflags &= ~PSL_VM; 464 regs->tf_cs = _ucodesel; 465 regs->tf_ds = _udatasel; 466 regs->tf_es = _udatasel; 467 regs->tf_fs = _udatasel; 468 load_gs(_udatasel); 469 regs->tf_ss = _udatasel; 470} 471 472/* 473 * System call to cleanup state after a signal 474 * has been taken. Reset signal mask and 475 * stack state from context left by sendsig (above). 476 * Return to previous pc and psl as specified by 477 * context left by sendsig. Check carefully to 478 * make sure that the user has not modified the 479 * psl to gain improper privileges or to cause 480 * a machine fault. 481 */ 482int 483linux_sigreturn(p, args) 484 struct proc *p; 485 struct linux_sigreturn_args *args; 486{ 487 struct linux_sigframe frame; 488 register struct trapframe *regs; 489 linux_sigset_t lmask; 490 int eflags, i; 491 492 regs = p->p_md.md_regs; 493 494#ifdef DEBUG 495 printf("Linux-emul(%ld): linux_sigreturn(%p)\n", 496 (long)p->p_pid, (void *)args->sfp); 497#endif 498 /* 499 * The trampoline code hands us the sigframe. 500 * It is unsafe to keep track of it ourselves, in the event that a 501 * program jumps out of a signal handler. 502 */ 503 if (copyin((caddr_t)args->sfp, &frame, sizeof(frame)) != 0) 504 return (EFAULT); 505 506 /* 507 * Check for security violations. 508 */ 509#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) 510 eflags = frame.sf_sc.sc_eflags; 511 /* 512 * XXX do allow users to change the privileged flag PSL_RF. The 513 * cpu sets PSL_RF in tf_eflags for faults. Debuggers should 514 * sometimes set it there too. tf_eflags is kept in the signal 515 * context during signal handling and there is no other place 516 * to remember it, so the PSL_RF bit may be corrupted by the 517 * signal handler without us knowing. Corruption of the PSL_RF 518 * bit at worst causes one more or one less debugger trap, so 519 * allowing it is fairly harmless. 520 */ 521 if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) { 522 return(EINVAL); 523 } 524 525 /* 526 * Don't allow users to load a valid privileged %cs. Let the 527 * hardware check for invalid selectors, excess privilege in 528 * other selectors, invalid %eip's and invalid %esp's. 529 */ 530#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) 531 if (!CS_SECURE(frame.sf_sc.sc_cs)) { 532 trapsignal(p, SIGBUS, T_PROTFLT); 533 return(EINVAL); 534 } 535 536 lmask.__bits[0] = frame.sf_sc.sc_mask; 537 for (i = 0; i < (LINUX_NSIG_WORDS-1); i++) 538 lmask.__bits[i+1] = frame.sf_extramask[i];
|
| 539 PROC_LOCK(p);
|
527 linux_to_bsd_sigset(&lmask, &p->p_sigmask); 528 SIG_CANTMASK(p->p_sigmask);
| 540 linux_to_bsd_sigset(&lmask, &p->p_sigmask); 541 SIG_CANTMASK(p->p_sigmask);
|
| 542 PROC_UNLOCK(p);
|
529 530 /* 531 * Restore signal context. 532 */ 533 /* %gs was restored by the trampoline. */ 534 regs->tf_fs = frame.sf_sc.sc_fs; 535 regs->tf_es = frame.sf_sc.sc_es; 536 regs->tf_ds = frame.sf_sc.sc_ds; 537 regs->tf_edi = frame.sf_sc.sc_edi; 538 regs->tf_esi = frame.sf_sc.sc_esi; 539 regs->tf_ebp = frame.sf_sc.sc_ebp; 540 regs->tf_ebx = frame.sf_sc.sc_ebx; 541 regs->tf_edx = frame.sf_sc.sc_edx; 542 regs->tf_ecx = frame.sf_sc.sc_ecx; 543 regs->tf_eax = frame.sf_sc.sc_eax; 544 regs->tf_eip = frame.sf_sc.sc_eip; 545 regs->tf_cs = frame.sf_sc.sc_cs; 546 regs->tf_eflags = eflags; 547 regs->tf_esp = frame.sf_sc.sc_esp_at_signal; 548 regs->tf_ss = frame.sf_sc.sc_ss; 549 550 return (EJUSTRETURN); 551} 552 553/* 554 * System call to cleanup state after a signal 555 * has been taken. Reset signal mask and 556 * stack state from context left by rt_sendsig (above). 557 * Return to previous pc and psl as specified by 558 * context left by sendsig. Check carefully to 559 * make sure that the user has not modified the 560 * psl to gain improper privileges or to cause 561 * a machine fault. 562 */ 563int 564linux_rt_sigreturn(p, args) 565 struct proc *p; 566 struct linux_rt_sigreturn_args *args; 567{ 568 struct sigaltstack_args sasargs; 569 struct linux_ucontext uc; 570 struct linux_sigcontext *context; 571 linux_stack_t *lss; 572 stack_t *ss; 573 register struct trapframe *regs; 574 int eflags; 575 caddr_t sg = stackgap_init(); 576 577 regs = p->p_md.md_regs; 578 579#ifdef DEBUG 580 printf("Linux-emul(%ld): linux_rt_sigreturn(%p)\n", 581 (long)p->p_pid, (void *)args->ucp); 582#endif 583 /* 584 * The trampoline code hands us the ucontext. 585 * It is unsafe to keep track of it ourselves, in the event that a 586 * program jumps out of a signal handler. 587 */ 588 if (copyin((caddr_t)args->ucp, &uc, sizeof(uc)) != 0) 589 return (EFAULT); 590 591 context = &uc.uc_mcontext; 592 593 /* 594 * Check for security violations. 595 */ 596#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) 597 eflags = context->sc_eflags; 598 /* 599 * XXX do allow users to change the privileged flag PSL_RF. The 600 * cpu sets PSL_RF in tf_eflags for faults. Debuggers should 601 * sometimes set it there too. tf_eflags is kept in the signal 602 * context during signal handling and there is no other place 603 * to remember it, so the PSL_RF bit may be corrupted by the 604 * signal handler without us knowing. Corruption of the PSL_RF 605 * bit at worst causes one more or one less debugger trap, so 606 * allowing it is fairly harmless. 607 */ 608 if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) { 609 return(EINVAL); 610 } 611 612 /* 613 * Don't allow users to load a valid privileged %cs. Let the 614 * hardware check for invalid selectors, excess privilege in 615 * other selectors, invalid %eip's and invalid %esp's. 616 */ 617#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) 618 if (!CS_SECURE(context->sc_cs)) { 619 trapsignal(p, SIGBUS, T_PROTFLT); 620 return(EINVAL); 621 } 622
| 543 544 /* 545 * Restore signal context. 546 */ 547 /* %gs was restored by the trampoline. */ 548 regs->tf_fs = frame.sf_sc.sc_fs; 549 regs->tf_es = frame.sf_sc.sc_es; 550 regs->tf_ds = frame.sf_sc.sc_ds; 551 regs->tf_edi = frame.sf_sc.sc_edi; 552 regs->tf_esi = frame.sf_sc.sc_esi; 553 regs->tf_ebp = frame.sf_sc.sc_ebp; 554 regs->tf_ebx = frame.sf_sc.sc_ebx; 555 regs->tf_edx = frame.sf_sc.sc_edx; 556 regs->tf_ecx = frame.sf_sc.sc_ecx; 557 regs->tf_eax = frame.sf_sc.sc_eax; 558 regs->tf_eip = frame.sf_sc.sc_eip; 559 regs->tf_cs = frame.sf_sc.sc_cs; 560 regs->tf_eflags = eflags; 561 regs->tf_esp = frame.sf_sc.sc_esp_at_signal; 562 regs->tf_ss = frame.sf_sc.sc_ss; 563 564 return (EJUSTRETURN); 565} 566 567/* 568 * System call to cleanup state after a signal 569 * has been taken. Reset signal mask and 570 * stack state from context left by rt_sendsig (above). 571 * Return to previous pc and psl as specified by 572 * context left by sendsig. Check carefully to 573 * make sure that the user has not modified the 574 * psl to gain improper privileges or to cause 575 * a machine fault. 576 */ 577int 578linux_rt_sigreturn(p, args) 579 struct proc *p; 580 struct linux_rt_sigreturn_args *args; 581{ 582 struct sigaltstack_args sasargs; 583 struct linux_ucontext uc; 584 struct linux_sigcontext *context; 585 linux_stack_t *lss; 586 stack_t *ss; 587 register struct trapframe *regs; 588 int eflags; 589 caddr_t sg = stackgap_init(); 590 591 regs = p->p_md.md_regs; 592 593#ifdef DEBUG 594 printf("Linux-emul(%ld): linux_rt_sigreturn(%p)\n", 595 (long)p->p_pid, (void *)args->ucp); 596#endif 597 /* 598 * The trampoline code hands us the ucontext. 599 * It is unsafe to keep track of it ourselves, in the event that a 600 * program jumps out of a signal handler. 601 */ 602 if (copyin((caddr_t)args->ucp, &uc, sizeof(uc)) != 0) 603 return (EFAULT); 604 605 context = &uc.uc_mcontext; 606 607 /* 608 * Check for security violations. 609 */ 610#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) 611 eflags = context->sc_eflags; 612 /* 613 * XXX do allow users to change the privileged flag PSL_RF. The 614 * cpu sets PSL_RF in tf_eflags for faults. Debuggers should 615 * sometimes set it there too. tf_eflags is kept in the signal 616 * context during signal handling and there is no other place 617 * to remember it, so the PSL_RF bit may be corrupted by the 618 * signal handler without us knowing. Corruption of the PSL_RF 619 * bit at worst causes one more or one less debugger trap, so 620 * allowing it is fairly harmless. 621 */ 622 if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) { 623 return(EINVAL); 624 } 625 626 /* 627 * Don't allow users to load a valid privileged %cs. Let the 628 * hardware check for invalid selectors, excess privilege in 629 * other selectors, invalid %eip's and invalid %esp's. 630 */ 631#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) 632 if (!CS_SECURE(context->sc_cs)) { 633 trapsignal(p, SIGBUS, T_PROTFLT); 634 return(EINVAL); 635 } 636
|
| 637 PROC_LOCK(p);
|
623 linux_to_bsd_sigset(&uc.uc_sigmask, &p->p_sigmask); 624 SIG_CANTMASK(p->p_sigmask);
| 638 linux_to_bsd_sigset(&uc.uc_sigmask, &p->p_sigmask); 639 SIG_CANTMASK(p->p_sigmask);
|
| 640 PROC_UNLOCK(p);
|
625 626 /* 627 * Restore signal context 628 */ 629 /* %gs was restored by the trampoline. */ 630 regs->tf_fs = context->sc_fs; 631 regs->tf_es = context->sc_es; 632 regs->tf_ds = context->sc_ds; 633 regs->tf_edi = context->sc_edi; 634 regs->tf_esi = context->sc_esi; 635 regs->tf_ebp = context->sc_ebp; 636 regs->tf_ebx = context->sc_ebx; 637 regs->tf_edx = context->sc_edx; 638 regs->tf_ecx = context->sc_ecx; 639 regs->tf_eax = context->sc_eax; 640 regs->tf_eip = context->sc_eip; 641 regs->tf_cs = context->sc_cs; 642 regs->tf_eflags = eflags; 643 regs->tf_esp = context->sc_esp_at_signal; 644 regs->tf_ss = context->sc_ss; 645 646 /* 647 * call sigaltstack & ignore results.. 648 */ 649 ss = stackgap_alloc(&sg, sizeof(stack_t)); 650 lss = &uc.uc_stack; 651 ss->ss_sp = lss->ss_sp; 652 ss->ss_size = lss->ss_size; 653 ss->ss_flags = linux_to_bsd_sigaltstack(lss->ss_flags); 654 655#ifdef DEBUG 656 printf("Linux-emul(%ld): rt_sigret flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x\n", 657 (long)p->p_pid, ss->ss_flags, ss->ss_sp, ss->ss_size, context->sc_mask); 658#endif 659 sasargs.ss = ss; 660 sasargs.oss = NULL; 661 (void) sigaltstack(p, &sasargs); 662 663 return (EJUSTRETURN); 664} 665 666static void 667linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params) 668{ 669 args[0] = tf->tf_ebx; 670 args[1] = tf->tf_ecx; 671 args[2] = tf->tf_edx; 672 args[3] = tf->tf_esi; 673 args[4] = tf->tf_edi; 674 *params = NULL; /* no copyin */ 675} 676 677/* 678 * If a linux binary is exec'ing something, try this image activator 679 * first. We override standard shell script execution in order to 680 * be able to modify the interpreter path. We only do this if a linux 681 * binary is doing the exec, so we do not create an EXEC module for it. 682 */ 683static int exec_linux_imgact_try __P((struct image_params *iparams)); 684 685static int 686exec_linux_imgact_try(imgp) 687 struct image_params *imgp; 688{ 689 const char *head = (const char *)imgp->image_header; 690 int error = -1; 691 692 /* 693 * The interpreter for shell scripts run from a linux binary needs 694 * to be located in /compat/linux if possible in order to recursively 695 * maintain linux path emulation. 696 */ 697 if (((const short *)head)[0] == SHELLMAGIC) { 698 /* 699 * Run our normal shell image activator. If it succeeds attempt 700 * to use the alternate path for the interpreter. If an alternate 701 * path is found, use our stringspace to store it. 702 */ 703 if ((error = exec_shell_imgact(imgp)) == 0) { 704 char *rpath = NULL; 705 706 linux_emul_find(imgp->proc, NULL, linux_emul_path, 707 imgp->interpreter_name, &rpath, 0); 708 if (rpath != imgp->interpreter_name) { 709 int len = strlen(rpath) + 1; 710 711 if (len <= MAXSHELLCMDLEN) { 712 memcpy(imgp->interpreter_name, rpath, len); 713 } 714 free(rpath, M_TEMP); 715 } 716 } 717 } 718 return(error); 719} 720 721struct sysentvec linux_sysvec = { 722 LINUX_SYS_MAXSYSCALL, 723 linux_sysent, 724 0xff, 725 LINUX_SIGTBLSZ, 726 bsd_to_linux_signal, 727 ELAST + 1, 728 bsd_to_linux_errno, 729 translate_traps, 730 linux_fixup, 731 linux_sendsig, 732 linux_sigcode, 733 &linux_szsigcode, 734 linux_prepsyscall, 735 "Linux a.out", 736 aout_coredump, 737 exec_linux_imgact_try, 738 LINUX_MINSIGSTKSZ 739}; 740 741struct sysentvec elf_linux_sysvec = { 742 LINUX_SYS_MAXSYSCALL, 743 linux_sysent, 744 0xff, 745 LINUX_SIGTBLSZ, 746 bsd_to_linux_signal, 747 ELAST + 1, 748 bsd_to_linux_errno, 749 translate_traps, 750 elf_linux_fixup, 751 linux_sendsig, 752 linux_sigcode, 753 &linux_szsigcode, 754 linux_prepsyscall, 755 "Linux ELF", 756 elf_coredump, 757 exec_linux_imgact_try, 758 LINUX_MINSIGSTKSZ 759}; 760 761static Elf32_Brandinfo linux_brand = { 762 ELFOSABI_LINUX, 763 "/compat/linux", 764 "/lib/ld-linux.so.1", 765 &elf_linux_sysvec 766 }; 767 768static Elf32_Brandinfo linux_glibc2brand = { 769 ELFOSABI_LINUX, 770 "/compat/linux", 771 "/lib/ld-linux.so.2", 772 &elf_linux_sysvec 773 }; 774 775Elf32_Brandinfo *linux_brandlist[] = { 776 &linux_brand, 777 &linux_glibc2brand, 778 NULL 779 }; 780 781static int 782linux_elf_modevent(module_t mod, int type, void *data) 783{ 784 Elf32_Brandinfo **brandinfo; 785 int error; 786 787 error = 0; 788 789 switch(type) { 790 case MOD_LOAD: 791 for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL; 792 ++brandinfo) 793 if (elf_insert_brand_entry(*brandinfo) < 0) 794 error = EINVAL; 795 if (error == 0) { 796 linux_ioctl_register_handlers( 797 &linux_ioctl_handler_set); 798 if (bootverbose) 799 printf("Linux ELF exec handler installed\n"); 800 } else 801 printf("cannot insert Linux ELF brand handler\n"); 802 break; 803 case MOD_UNLOAD: 804 for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL; 805 ++brandinfo) 806 if (elf_brand_inuse(*brandinfo)) 807 error = EBUSY; 808 if (error == 0) { 809 for (brandinfo = &linux_brandlist[0]; 810 *brandinfo != NULL; ++brandinfo) 811 if (elf_remove_brand_entry(*brandinfo) < 0) 812 error = EINVAL; 813 } 814 if (error == 0) { 815 linux_ioctl_unregister_handlers( 816 &linux_ioctl_handler_set); 817 if (bootverbose) 818 printf("Linux ELF exec handler removed\n"); 819 } else 820 printf("Could not deinstall ELF interpreter entry\n"); 821 break; 822 default: 823 break; 824 } 825 return error; 826} 827 828static moduledata_t linux_elf_mod = { 829 "linuxelf", 830 linux_elf_modevent, 831 0 832}; 833 834DECLARE_MODULE(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
| 641 642 /* 643 * Restore signal context 644 */ 645 /* %gs was restored by the trampoline. */ 646 regs->tf_fs = context->sc_fs; 647 regs->tf_es = context->sc_es; 648 regs->tf_ds = context->sc_ds; 649 regs->tf_edi = context->sc_edi; 650 regs->tf_esi = context->sc_esi; 651 regs->tf_ebp = context->sc_ebp; 652 regs->tf_ebx = context->sc_ebx; 653 regs->tf_edx = context->sc_edx; 654 regs->tf_ecx = context->sc_ecx; 655 regs->tf_eax = context->sc_eax; 656 regs->tf_eip = context->sc_eip; 657 regs->tf_cs = context->sc_cs; 658 regs->tf_eflags = eflags; 659 regs->tf_esp = context->sc_esp_at_signal; 660 regs->tf_ss = context->sc_ss; 661 662 /* 663 * call sigaltstack & ignore results.. 664 */ 665 ss = stackgap_alloc(&sg, sizeof(stack_t)); 666 lss = &uc.uc_stack; 667 ss->ss_sp = lss->ss_sp; 668 ss->ss_size = lss->ss_size; 669 ss->ss_flags = linux_to_bsd_sigaltstack(lss->ss_flags); 670 671#ifdef DEBUG 672 printf("Linux-emul(%ld): rt_sigret flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x\n", 673 (long)p->p_pid, ss->ss_flags, ss->ss_sp, ss->ss_size, context->sc_mask); 674#endif 675 sasargs.ss = ss; 676 sasargs.oss = NULL; 677 (void) sigaltstack(p, &sasargs); 678 679 return (EJUSTRETURN); 680} 681 682static void 683linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params) 684{ 685 args[0] = tf->tf_ebx; 686 args[1] = tf->tf_ecx; 687 args[2] = tf->tf_edx; 688 args[3] = tf->tf_esi; 689 args[4] = tf->tf_edi; 690 *params = NULL; /* no copyin */ 691} 692 693/* 694 * If a linux binary is exec'ing something, try this image activator 695 * first. We override standard shell script execution in order to 696 * be able to modify the interpreter path. We only do this if a linux 697 * binary is doing the exec, so we do not create an EXEC module for it. 698 */ 699static int exec_linux_imgact_try __P((struct image_params *iparams)); 700 701static int 702exec_linux_imgact_try(imgp) 703 struct image_params *imgp; 704{ 705 const char *head = (const char *)imgp->image_header; 706 int error = -1; 707 708 /* 709 * The interpreter for shell scripts run from a linux binary needs 710 * to be located in /compat/linux if possible in order to recursively 711 * maintain linux path emulation. 712 */ 713 if (((const short *)head)[0] == SHELLMAGIC) { 714 /* 715 * Run our normal shell image activator. If it succeeds attempt 716 * to use the alternate path for the interpreter. If an alternate 717 * path is found, use our stringspace to store it. 718 */ 719 if ((error = exec_shell_imgact(imgp)) == 0) { 720 char *rpath = NULL; 721 722 linux_emul_find(imgp->proc, NULL, linux_emul_path, 723 imgp->interpreter_name, &rpath, 0); 724 if (rpath != imgp->interpreter_name) { 725 int len = strlen(rpath) + 1; 726 727 if (len <= MAXSHELLCMDLEN) { 728 memcpy(imgp->interpreter_name, rpath, len); 729 } 730 free(rpath, M_TEMP); 731 } 732 } 733 } 734 return(error); 735} 736 737struct sysentvec linux_sysvec = { 738 LINUX_SYS_MAXSYSCALL, 739 linux_sysent, 740 0xff, 741 LINUX_SIGTBLSZ, 742 bsd_to_linux_signal, 743 ELAST + 1, 744 bsd_to_linux_errno, 745 translate_traps, 746 linux_fixup, 747 linux_sendsig, 748 linux_sigcode, 749 &linux_szsigcode, 750 linux_prepsyscall, 751 "Linux a.out", 752 aout_coredump, 753 exec_linux_imgact_try, 754 LINUX_MINSIGSTKSZ 755}; 756 757struct sysentvec elf_linux_sysvec = { 758 LINUX_SYS_MAXSYSCALL, 759 linux_sysent, 760 0xff, 761 LINUX_SIGTBLSZ, 762 bsd_to_linux_signal, 763 ELAST + 1, 764 bsd_to_linux_errno, 765 translate_traps, 766 elf_linux_fixup, 767 linux_sendsig, 768 linux_sigcode, 769 &linux_szsigcode, 770 linux_prepsyscall, 771 "Linux ELF", 772 elf_coredump, 773 exec_linux_imgact_try, 774 LINUX_MINSIGSTKSZ 775}; 776 777static Elf32_Brandinfo linux_brand = { 778 ELFOSABI_LINUX, 779 "/compat/linux", 780 "/lib/ld-linux.so.1", 781 &elf_linux_sysvec 782 }; 783 784static Elf32_Brandinfo linux_glibc2brand = { 785 ELFOSABI_LINUX, 786 "/compat/linux", 787 "/lib/ld-linux.so.2", 788 &elf_linux_sysvec 789 }; 790 791Elf32_Brandinfo *linux_brandlist[] = { 792 &linux_brand, 793 &linux_glibc2brand, 794 NULL 795 }; 796 797static int 798linux_elf_modevent(module_t mod, int type, void *data) 799{ 800 Elf32_Brandinfo **brandinfo; 801 int error; 802 803 error = 0; 804 805 switch(type) { 806 case MOD_LOAD: 807 for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL; 808 ++brandinfo) 809 if (elf_insert_brand_entry(*brandinfo) < 0) 810 error = EINVAL; 811 if (error == 0) { 812 linux_ioctl_register_handlers( 813 &linux_ioctl_handler_set); 814 if (bootverbose) 815 printf("Linux ELF exec handler installed\n"); 816 } else 817 printf("cannot insert Linux ELF brand handler\n"); 818 break; 819 case MOD_UNLOAD: 820 for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL; 821 ++brandinfo) 822 if (elf_brand_inuse(*brandinfo)) 823 error = EBUSY; 824 if (error == 0) { 825 for (brandinfo = &linux_brandlist[0]; 826 *brandinfo != NULL; ++brandinfo) 827 if (elf_remove_brand_entry(*brandinfo) < 0) 828 error = EINVAL; 829 } 830 if (error == 0) { 831 linux_ioctl_unregister_handlers( 832 &linux_ioctl_handler_set); 833 if (bootverbose) 834 printf("Linux ELF exec handler removed\n"); 835 } else 836 printf("Could not deinstall ELF interpreter entry\n"); 837 break; 838 default: 839 break; 840 } 841 return error; 842} 843 844static moduledata_t linux_elf_mod = { 845 "linuxelf", 846 linux_elf_modevent, 847 0 848}; 849 850DECLARE_MODULE(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
|