1 /*- 2 * Copyright (c) 2003 Peter Wemm 3 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * William Jolitz. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 #include "opt_compat.h" 38 39 #include <sys/param.h> 40 #include <sys/exec.h> 41 #include <sys/fcntl.h> 42 #include <sys/imgact.h> 43 #include <sys/kernel.h> 44 #include <sys/lock.h> 45 #include <sys/malloc.h> 46 #include <sys/mutex.h> 47 #include <sys/mman.h> 48 #include <sys/namei.h> 49 #include <sys/pioctl.h> 50 #include <sys/proc.h> 51 #include <sys/procfs.h> 52 #include <sys/resourcevar.h> 53 #include <sys/systm.h> 54 #include <sys/signalvar.h> 55 #include <sys/stat.h> 56 #include <sys/sx.h> 57 #include <sys/syscall.h> 58 #include <sys/syscallsubr.h> 59 #include <sys/sysctl.h> 60 #include <sys/sysent.h> 61 #include <sys/vnode.h> 62 63 #include <vm/vm.h> 64 #include <vm/vm_kern.h> 65 #include <vm/vm_param.h> 66 #include <vm/pmap.h> 67 #include <vm/vm_map.h> 68 #include <vm/vm_object.h> 69 #include <vm/vm_extern.h> 70 71 #include <compat/freebsd32/freebsd32_signal.h> 72 #include <compat/freebsd32/freebsd32_util.h> 73 #include <compat/freebsd32/freebsd32_proto.h> 74 #include <compat/ia32/ia32_signal.h> 75 #include <machine/psl.h> 76 #include <machine/segments.h> 77 #include <machine/specialreg.h> 78 #include <machine/frame.h> 79 #include <machine/md_var.h> 80 #include <machine/pcb.h> 81 #include <machine/cpufunc.h> 82 83 #ifdef COMPAT_FREEBSD4 84 static void freebsd4_ia32_sendsig(sig_t, ksiginfo_t *, sigset_t *); 85 #endif 86 static void ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp); 87 static int ia32_set_fpcontext(struct thread *td, const struct ia32_mcontext *mcp); 88 89 #define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) 90 #define EFL_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) 91 92 static void 93 ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp) 94 { 95 96 /* 97 * XXX Format of 64bit and 32bit FXSAVE areas differs. FXSAVE 98 * in 32bit mode saves %cs and %ds, while on 64bit it saves 99 * 64bit instruction and data pointers. Ignore the difference 100 * for now, it should be irrelevant for most applications. 101 */ 102 mcp->mc_ownedfp = fpugetregs(td); 103 bcopy(&td->td_pcb->pcb_user_save, &mcp->mc_fpstate, 104 sizeof(mcp->mc_fpstate)); 105 mcp->mc_fpformat = fpuformat(); 106 } 107 108 static int 109 ia32_set_fpcontext(struct thread *td, const struct ia32_mcontext *mcp) 110 { 111 112 if (mcp->mc_fpformat == _MC_FPFMT_NODEV) 113 return (0); 114 else if (mcp->mc_fpformat != _MC_FPFMT_XMM) 115 return (EINVAL); 116 else if (mcp->mc_ownedfp == _MC_FPOWNED_NONE) 117 /* We don't care what state is left in the FPU or PCB. */ 118 fpstate_drop(td); 119 else if (mcp->mc_ownedfp == _MC_FPOWNED_FPU || 120 mcp->mc_ownedfp == _MC_FPOWNED_PCB) { 121 fpusetregs(td, (struct savefpu *)&mcp->mc_fpstate); 122 } else 123 return (EINVAL); 124 return (0); 125 } 126 127 /* 128 * Get machine context. 129 */ 130 static int 131 ia32_get_mcontext(struct thread *td, struct ia32_mcontext *mcp, int flags) 132 { 133 struct pcb *pcb; 134 struct trapframe *tp; 135 136 pcb = td->td_pcb; 137 tp = td->td_frame; 138 139 PROC_LOCK(curthread->td_proc); 140 mcp->mc_onstack = sigonstack(tp->tf_rsp); 141 PROC_UNLOCK(curthread->td_proc); 142 /* Entry into kernel always sets TF_HASSEGS */ 143 mcp->mc_gs = tp->tf_gs; 144 mcp->mc_fs = tp->tf_fs; 145 mcp->mc_es = tp->tf_es; 146 mcp->mc_ds = tp->tf_ds; 147 mcp->mc_edi = tp->tf_rdi; 148 mcp->mc_esi = tp->tf_rsi; 149 mcp->mc_ebp = tp->tf_rbp; 150 mcp->mc_isp = tp->tf_rsp; 151 mcp->mc_eflags = tp->tf_rflags; 152 if (flags & GET_MC_CLEAR_RET) { 153 mcp->mc_eax = 0; 154 mcp->mc_edx = 0; 155 mcp->mc_eflags &= ~PSL_C; 156 } else { 157 mcp->mc_eax = tp->tf_rax; 158 mcp->mc_edx = tp->tf_rdx; 159 } 160 mcp->mc_ebx = tp->tf_rbx; 161 mcp->mc_ecx = tp->tf_rcx; 162 mcp->mc_eip = tp->tf_rip; 163 mcp->mc_cs = tp->tf_cs; 164 mcp->mc_esp = tp->tf_rsp; 165 mcp->mc_ss = tp->tf_ss; 166 mcp->mc_len = sizeof(*mcp); 167 ia32_get_fpcontext(td, mcp); 168 mcp->mc_fsbase = pcb->pcb_fsbase; 169 mcp->mc_gsbase = pcb->pcb_gsbase; 170 bzero(mcp->mc_spare1, sizeof(mcp->mc_spare1)); 171 bzero(mcp->mc_spare2, sizeof(mcp->mc_spare2)); 172 set_pcb_flags(pcb, PCB_FULL_IRET); 173 return (0); 174 } 175 176 /* 177 * Set machine context. 178 * 179 * However, we don't set any but the user modifiable flags, and we won't 180 * touch the cs selector. 181 */ 182 static int 183 ia32_set_mcontext(struct thread *td, const struct ia32_mcontext *mcp) 184 { 185 struct trapframe *tp; 186 long rflags; 187 int ret; 188 189 tp = td->td_frame; 190 if (mcp->mc_len != sizeof(*mcp)) 191 return (EINVAL); 192 rflags = (mcp->mc_eflags & PSL_USERCHANGE) | 193 (tp->tf_rflags & ~PSL_USERCHANGE); 194 ret = ia32_set_fpcontext(td, mcp); 195 if (ret != 0) 196 return (ret); 197 tp->tf_gs = mcp->mc_gs; 198 tp->tf_fs = mcp->mc_fs; 199 tp->tf_es = mcp->mc_es; 200 tp->tf_ds = mcp->mc_ds; 201 tp->tf_flags = TF_HASSEGS; 202 tp->tf_rdi = mcp->mc_edi; 203 tp->tf_rsi = mcp->mc_esi; 204 tp->tf_rbp = mcp->mc_ebp; 205 tp->tf_rbx = mcp->mc_ebx; 206 tp->tf_rdx = mcp->mc_edx; 207 tp->tf_rcx = mcp->mc_ecx; 208 tp->tf_rax = mcp->mc_eax; 209 /* trapno, err */ 210 tp->tf_rip = mcp->mc_eip; 211 tp->tf_rflags = rflags; 212 tp->tf_rsp = mcp->mc_esp; 213 tp->tf_ss = mcp->mc_ss; 214 set_pcb_flags(td->td_pcb, PCB_FULL_IRET); 215 return (0); 216 } 217 218 /* 219 * The first two fields of a ucontext_t are the signal mask and 220 * the machine context. The next field is uc_link; we want to 221 * avoid destroying the link when copying out contexts. 222 */ 223 #define UC_COPY_SIZE offsetof(struct ia32_ucontext, uc_link) 224 225 int 226 freebsd32_getcontext(struct thread *td, struct freebsd32_getcontext_args *uap) 227 { 228 struct ia32_ucontext uc; 229 int ret; 230 231 if (uap->ucp == NULL) 232 ret = EINVAL; 233 else { 234 ia32_get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); 235 PROC_LOCK(td->td_proc); 236 uc.uc_sigmask = td->td_sigmask; 237 PROC_UNLOCK(td->td_proc); 238 bzero(&uc.__spare__, sizeof(uc.__spare__)); 239 ret = copyout(&uc, uap->ucp, UC_COPY_SIZE); 240 } 241 return (ret); 242 } 243 244 int 245 freebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap) 246 { 247 struct ia32_ucontext uc; 248 int ret; 249 250 if (uap->ucp == NULL) 251 ret = EINVAL; 252 else { 253 ret = copyin(uap->ucp, &uc, UC_COPY_SIZE); 254 if (ret == 0) { 255 ret = ia32_set_mcontext(td, &uc.uc_mcontext); 256 if (ret == 0) { 257 kern_sigprocmask(td, SIG_SETMASK, 258 &uc.uc_sigmask, NULL, 0); 259 } 260 } 261 } 262 return (ret == 0 ? EJUSTRETURN : ret); 263 } 264 265 int 266 freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap) 267 { 268 struct ia32_ucontext uc; 269 int ret; 270 271 if (uap->oucp == NULL || uap->ucp == NULL) 272 ret = EINVAL; 273 else { 274 ia32_get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); 275 PROC_LOCK(td->td_proc); 276 uc.uc_sigmask = td->td_sigmask; 277 PROC_UNLOCK(td->td_proc); 278 ret = copyout(&uc, uap->oucp, UC_COPY_SIZE); 279 if (ret == 0) { 280 ret = copyin(uap->ucp, &uc, UC_COPY_SIZE); 281 if (ret == 0) { 282 ret = ia32_set_mcontext(td, &uc.uc_mcontext); 283 if (ret == 0) { 284 kern_sigprocmask(td, SIG_SETMASK, 285 &uc.uc_sigmask, NULL, 0); 286 } 287 } 288 } 289 } 290 return (ret == 0 ? EJUSTRETURN : ret); 291 } 292 293 /* 294 * Send an interrupt to process. 295 * 296 * Stack is set up to allow sigcode stored 297 * at top to call routine, followed by kcall 298 * to sigreturn routine below. After sigreturn 299 * resets the signal mask, the stack, and the 300 * frame pointer, it returns to the user 301 * specified pc, psl. 302 */ 303 #ifdef COMPAT_FREEBSD4 304 static void 305 freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 306 { 307 struct ia32_sigframe4 sf, *sfp; 308 struct siginfo32 siginfo; 309 struct proc *p; 310 struct thread *td; 311 struct sigacts *psp; 312 struct trapframe *regs; 313 int oonstack; 314 int sig; 315 316 td = curthread; 317 p = td->td_proc; 318 siginfo_to_siginfo32(&ksi->ksi_info, &siginfo); 319 320 PROC_LOCK_ASSERT(p, MA_OWNED); 321 sig = siginfo.si_signo; 322 psp = p->p_sigacts; 323 mtx_assert(&psp->ps_mtx, MA_OWNED); 324 regs = td->td_frame; 325 oonstack = sigonstack(regs->tf_rsp); 326 327 /* Save user context. */ 328 bzero(&sf, sizeof(sf)); 329 sf.sf_uc.uc_sigmask = *mask; 330 sf.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp; 331 sf.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size; 332 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 333 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 334 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 335 sf.sf_uc.uc_mcontext.mc_edi = regs->tf_rdi; 336 sf.sf_uc.uc_mcontext.mc_esi = regs->tf_rsi; 337 sf.sf_uc.uc_mcontext.mc_ebp = regs->tf_rbp; 338 sf.sf_uc.uc_mcontext.mc_isp = regs->tf_rsp; /* XXX */ 339 sf.sf_uc.uc_mcontext.mc_ebx = regs->tf_rbx; 340 sf.sf_uc.uc_mcontext.mc_edx = regs->tf_rdx; 341 sf.sf_uc.uc_mcontext.mc_ecx = regs->tf_rcx; 342 sf.sf_uc.uc_mcontext.mc_eax = regs->tf_rax; 343 sf.sf_uc.uc_mcontext.mc_trapno = regs->tf_trapno; 344 sf.sf_uc.uc_mcontext.mc_err = regs->tf_err; 345 sf.sf_uc.uc_mcontext.mc_eip = regs->tf_rip; 346 sf.sf_uc.uc_mcontext.mc_cs = regs->tf_cs; 347 sf.sf_uc.uc_mcontext.mc_eflags = regs->tf_rflags; 348 sf.sf_uc.uc_mcontext.mc_esp = regs->tf_rsp; 349 sf.sf_uc.uc_mcontext.mc_ss = regs->tf_ss; 350 sf.sf_uc.uc_mcontext.mc_ds = regs->tf_ds; 351 sf.sf_uc.uc_mcontext.mc_es = regs->tf_es; 352 sf.sf_uc.uc_mcontext.mc_fs = regs->tf_fs; 353 sf.sf_uc.uc_mcontext.mc_gs = regs->tf_gs; 354 bzero(sf.sf_uc.uc_mcontext.mc_fpregs, 355 sizeof(sf.sf_uc.uc_mcontext.mc_fpregs)); 356 bzero(sf.sf_uc.uc_mcontext.__spare__, 357 sizeof(sf.sf_uc.uc_mcontext.__spare__)); 358 bzero(sf.sf_uc.__spare__, sizeof(sf.sf_uc.__spare__)); 359 360 /* Allocate space for the signal handler context. */ 361 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 362 SIGISMEMBER(psp->ps_sigonstack, sig)) { 363 sfp = (struct ia32_sigframe4 *)(td->td_sigstk.ss_sp + 364 td->td_sigstk.ss_size - sizeof(sf)); 365 } else 366 sfp = (struct ia32_sigframe4 *)regs->tf_rsp - 1; 367 PROC_UNLOCK(p); 368 369 /* Translate the signal if appropriate. */ 370 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 371 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 372 373 /* Build the argument list for the signal handler. */ 374 sf.sf_signum = sig; 375 sf.sf_ucontext = (register_t)&sfp->sf_uc; 376 bzero(&sf.sf_si, sizeof(sf.sf_si)); 377 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 378 /* Signal handler installed with SA_SIGINFO. */ 379 sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si; 380 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 381 382 /* Fill in POSIX parts */ 383 sf.sf_si = siginfo; 384 sf.sf_si.si_signo = sig; 385 } else { 386 /* Old FreeBSD-style arguments. */ 387 sf.sf_siginfo = siginfo.si_code; 388 sf.sf_addr = (u_int32_t)siginfo.si_addr; 389 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 390 } 391 mtx_unlock(&psp->ps_mtx); 392 393 /* 394 * Copy the sigframe out to the user's stack. 395 */ 396 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { 397 #ifdef DEBUG 398 printf("process %ld has trashed its stack\n", (long)p->p_pid); 399 #endif 400 PROC_LOCK(p); 401 sigexit(td, SIGILL); 402 } 403 404 regs->tf_rsp = (uintptr_t)sfp; 405 regs->tf_rip = p->p_sysent->sv_sigcode_base + sz_ia32_sigcode - 406 sz_freebsd4_ia32_sigcode; 407 regs->tf_rflags &= ~(PSL_T | PSL_D); 408 regs->tf_cs = _ucode32sel; 409 regs->tf_ss = _udatasel; 410 regs->tf_ds = _udatasel; 411 regs->tf_es = _udatasel; 412 set_pcb_flags(td->td_pcb, PCB_FULL_IRET); 413 /* leave user %fs and %gs untouched */ 414 PROC_LOCK(p); 415 mtx_lock(&psp->ps_mtx); 416 } 417 #endif /* COMPAT_FREEBSD4 */ 418 419 void 420 ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 421 { 422 struct ia32_sigframe sf, *sfp; 423 struct siginfo32 siginfo; 424 struct proc *p; 425 struct thread *td; 426 struct sigacts *psp; 427 char *sp; 428 struct trapframe *regs; 429 int oonstack; 430 int sig; 431 432 siginfo_to_siginfo32(&ksi->ksi_info, &siginfo); 433 td = curthread; 434 p = td->td_proc; 435 PROC_LOCK_ASSERT(p, MA_OWNED); 436 sig = siginfo.si_signo; 437 psp = p->p_sigacts; 438 #ifdef COMPAT_FREEBSD4 439 if (SIGISMEMBER(psp->ps_freebsd4, sig)) { 440 freebsd4_ia32_sendsig(catcher, ksi, mask); 441 return; 442 } 443 #endif 444 mtx_assert(&psp->ps_mtx, MA_OWNED); 445 regs = td->td_frame; 446 oonstack = sigonstack(regs->tf_rsp); 447 448 /* Save user context. */ 449 bzero(&sf, sizeof(sf)); 450 sf.sf_uc.uc_sigmask = *mask; 451 sf.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp; 452 sf.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size; 453 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 454 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 455 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 456 sf.sf_uc.uc_mcontext.mc_edi = regs->tf_rdi; 457 sf.sf_uc.uc_mcontext.mc_esi = regs->tf_rsi; 458 sf.sf_uc.uc_mcontext.mc_ebp = regs->tf_rbp; 459 sf.sf_uc.uc_mcontext.mc_isp = regs->tf_rsp; /* XXX */ 460 sf.sf_uc.uc_mcontext.mc_ebx = regs->tf_rbx; 461 sf.sf_uc.uc_mcontext.mc_edx = regs->tf_rdx; 462 sf.sf_uc.uc_mcontext.mc_ecx = regs->tf_rcx; 463 sf.sf_uc.uc_mcontext.mc_eax = regs->tf_rax; 464 sf.sf_uc.uc_mcontext.mc_trapno = regs->tf_trapno; 465 sf.sf_uc.uc_mcontext.mc_err = regs->tf_err; 466 sf.sf_uc.uc_mcontext.mc_eip = regs->tf_rip; 467 sf.sf_uc.uc_mcontext.mc_cs = regs->tf_cs; 468 sf.sf_uc.uc_mcontext.mc_eflags = regs->tf_rflags; 469 sf.sf_uc.uc_mcontext.mc_esp = regs->tf_rsp; 470 sf.sf_uc.uc_mcontext.mc_ss = regs->tf_ss; 471 sf.sf_uc.uc_mcontext.mc_ds = regs->tf_ds; 472 sf.sf_uc.uc_mcontext.mc_es = regs->tf_es; 473 sf.sf_uc.uc_mcontext.mc_fs = regs->tf_fs; 474 sf.sf_uc.uc_mcontext.mc_gs = regs->tf_gs; 475 sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); /* magic */ 476 ia32_get_fpcontext(td, &sf.sf_uc.uc_mcontext); 477 fpstate_drop(td); 478 sf.sf_uc.uc_mcontext.mc_fsbase = td->td_pcb->pcb_fsbase; 479 sf.sf_uc.uc_mcontext.mc_gsbase = td->td_pcb->pcb_gsbase; 480 bzero(sf.sf_uc.__spare__, sizeof(sf.sf_uc.__spare__)); 481 482 /* Allocate space for the signal handler context. */ 483 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 484 SIGISMEMBER(psp->ps_sigonstack, sig)) { 485 sp = td->td_sigstk.ss_sp + 486 td->td_sigstk.ss_size - sizeof(sf); 487 } else 488 sp = (char *)regs->tf_rsp - sizeof(sf); 489 /* Align to 16 bytes. */ 490 sfp = (struct ia32_sigframe *)((uintptr_t)sp & ~0xF); 491 PROC_UNLOCK(p); 492 493 /* Translate the signal if appropriate. */ 494 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 495 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 496 497 /* Build the argument list for the signal handler. */ 498 sf.sf_signum = sig; 499 sf.sf_ucontext = (register_t)&sfp->sf_uc; 500 bzero(&sf.sf_si, sizeof(sf.sf_si)); 501 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 502 /* Signal handler installed with SA_SIGINFO. */ 503 sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si; 504 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 505 506 /* Fill in POSIX parts */ 507 sf.sf_si = siginfo; 508 sf.sf_si.si_signo = sig; 509 } else { 510 /* Old FreeBSD-style arguments. */ 511 sf.sf_siginfo = siginfo.si_code; 512 sf.sf_addr = (u_int32_t)siginfo.si_addr; 513 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 514 } 515 mtx_unlock(&psp->ps_mtx); 516 517 /* 518 * Copy the sigframe out to the user's stack. 519 */ 520 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { 521 #ifdef DEBUG 522 printf("process %ld has trashed its stack\n", (long)p->p_pid); 523 #endif 524 PROC_LOCK(p); 525 sigexit(td, SIGILL); 526 } 527 528 regs->tf_rsp = (uintptr_t)sfp; 529 regs->tf_rip = p->p_sysent->sv_sigcode_base; 530 regs->tf_rflags &= ~(PSL_T | PSL_D); 531 regs->tf_cs = _ucode32sel; 532 regs->tf_ss = _udatasel; 533 regs->tf_ds = _udatasel; 534 regs->tf_es = _udatasel; 535 set_pcb_flags(td->td_pcb, PCB_FULL_IRET); 536 /* XXXKIB leave user %fs and %gs untouched */ 537 PROC_LOCK(p); 538 mtx_lock(&psp->ps_mtx); 539 } 540 541 /* 542 * System call to cleanup state after a signal 543 * has been taken. Reset signal mask and 544 * stack state from context left by sendsig (above). 545 * Return to previous pc and psl as specified by 546 * context left by sendsig. Check carefully to 547 * make sure that the user has not modified the 548 * state to gain improper privileges. 549 */ 550 #ifdef COMPAT_FREEBSD4 551 /* 552 * MPSAFE 553 */ 554 int 555 freebsd4_freebsd32_sigreturn(td, uap) 556 struct thread *td; 557 struct freebsd4_freebsd32_sigreturn_args /* { 558 const struct freebsd4_freebsd32_ucontext *sigcntxp; 559 } */ *uap; 560 { 561 struct ia32_ucontext4 uc; 562 struct trapframe *regs; 563 struct ia32_ucontext4 *ucp; 564 int cs, eflags, error; 565 ksiginfo_t ksi; 566 567 error = copyin(uap->sigcntxp, &uc, sizeof(uc)); 568 if (error != 0) 569 return (error); 570 ucp = &uc; 571 regs = td->td_frame; 572 eflags = ucp->uc_mcontext.mc_eflags; 573 /* 574 * Don't allow users to change privileged or reserved flags. 575 */ 576 /* 577 * XXX do allow users to change the privileged flag PSL_RF. 578 * The cpu sets PSL_RF in tf_eflags for faults. Debuggers 579 * should sometimes set it there too. tf_eflags is kept in 580 * the signal context during signal handling and there is no 581 * other place to remember it, so the PSL_RF bit may be 582 * corrupted by the signal handler without us knowing. 583 * Corruption of the PSL_RF bit at worst causes one more or 584 * one less debugger trap, so allowing it is fairly harmless. 585 */ 586 if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) { 587 uprintf("pid %d (%s): freebsd4_freebsd32_sigreturn eflags = 0x%x\n", 588 td->td_proc->p_pid, td->td_name, eflags); 589 return (EINVAL); 590 } 591 592 /* 593 * Don't allow users to load a valid privileged %cs. Let the 594 * hardware check for invalid selectors, excess privilege in 595 * other selectors, invalid %eip's and invalid %esp's. 596 */ 597 cs = ucp->uc_mcontext.mc_cs; 598 if (!CS_SECURE(cs)) { 599 uprintf("pid %d (%s): freebsd4_sigreturn cs = 0x%x\n", 600 td->td_proc->p_pid, td->td_name, cs); 601 ksiginfo_init_trap(&ksi); 602 ksi.ksi_signo = SIGBUS; 603 ksi.ksi_code = BUS_OBJERR; 604 ksi.ksi_trapno = T_PROTFLT; 605 ksi.ksi_addr = (void *)regs->tf_rip; 606 trapsignal(td, &ksi); 607 return (EINVAL); 608 } 609 610 regs->tf_rdi = ucp->uc_mcontext.mc_edi; 611 regs->tf_rsi = ucp->uc_mcontext.mc_esi; 612 regs->tf_rbp = ucp->uc_mcontext.mc_ebp; 613 regs->tf_rbx = ucp->uc_mcontext.mc_ebx; 614 regs->tf_rdx = ucp->uc_mcontext.mc_edx; 615 regs->tf_rcx = ucp->uc_mcontext.mc_ecx; 616 regs->tf_rax = ucp->uc_mcontext.mc_eax; 617 regs->tf_trapno = ucp->uc_mcontext.mc_trapno; 618 regs->tf_err = ucp->uc_mcontext.mc_err; 619 regs->tf_rip = ucp->uc_mcontext.mc_eip; 620 regs->tf_cs = cs; 621 regs->tf_rflags = ucp->uc_mcontext.mc_eflags; 622 regs->tf_rsp = ucp->uc_mcontext.mc_esp; 623 regs->tf_ss = ucp->uc_mcontext.mc_ss; 624 regs->tf_ds = ucp->uc_mcontext.mc_ds; 625 regs->tf_es = ucp->uc_mcontext.mc_es; 626 regs->tf_fs = ucp->uc_mcontext.mc_fs; 627 regs->tf_gs = ucp->uc_mcontext.mc_gs; 628 629 kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0); 630 set_pcb_flags(td->td_pcb, PCB_FULL_IRET); 631 return (EJUSTRETURN); 632 } 633 #endif /* COMPAT_FREEBSD4 */ 634 635 /* 636 * MPSAFE 637 */ 638 int 639 freebsd32_sigreturn(td, uap) 640 struct thread *td; 641 struct freebsd32_sigreturn_args /* { 642 const struct freebsd32_ucontext *sigcntxp; 643 } */ *uap; 644 { 645 struct ia32_ucontext uc; 646 struct trapframe *regs; 647 struct ia32_ucontext *ucp; 648 int cs, eflags, error, ret; 649 ksiginfo_t ksi; 650 651 error = copyin(uap->sigcntxp, &uc, sizeof(uc)); 652 if (error != 0) 653 return (error); 654 ucp = &uc; 655 regs = td->td_frame; 656 eflags = ucp->uc_mcontext.mc_eflags; 657 /* 658 * Don't allow users to change privileged or reserved flags. 659 */ 660 /* 661 * XXX do allow users to change the privileged flag PSL_RF. 662 * The cpu sets PSL_RF in tf_eflags for faults. Debuggers 663 * should sometimes set it there too. tf_eflags is kept in 664 * the signal context during signal handling and there is no 665 * other place to remember it, so the PSL_RF bit may be 666 * corrupted by the signal handler without us knowing. 667 * Corruption of the PSL_RF bit at worst causes one more or 668 * one less debugger trap, so allowing it is fairly harmless. 669 */ 670 if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) { 671 uprintf("pid %d (%s): freebsd32_sigreturn eflags = 0x%x\n", 672 td->td_proc->p_pid, td->td_name, eflags); 673 return (EINVAL); 674 } 675 676 /* 677 * Don't allow users to load a valid privileged %cs. Let the 678 * hardware check for invalid selectors, excess privilege in 679 * other selectors, invalid %eip's and invalid %esp's. 680 */ 681 cs = ucp->uc_mcontext.mc_cs; 682 if (!CS_SECURE(cs)) { 683 uprintf("pid %d (%s): sigreturn cs = 0x%x\n", 684 td->td_proc->p_pid, td->td_name, cs); 685 ksiginfo_init_trap(&ksi); 686 ksi.ksi_signo = SIGBUS; 687 ksi.ksi_code = BUS_OBJERR; 688 ksi.ksi_trapno = T_PROTFLT; 689 ksi.ksi_addr = (void *)regs->tf_rip; 690 trapsignal(td, &ksi); 691 return (EINVAL); 692 } 693 694 ret = ia32_set_fpcontext(td, &ucp->uc_mcontext); 695 if (ret != 0) 696 return (ret); 697 698 regs->tf_rdi = ucp->uc_mcontext.mc_edi; 699 regs->tf_rsi = ucp->uc_mcontext.mc_esi; 700 regs->tf_rbp = ucp->uc_mcontext.mc_ebp; 701 regs->tf_rbx = ucp->uc_mcontext.mc_ebx; 702 regs->tf_rdx = ucp->uc_mcontext.mc_edx; 703 regs->tf_rcx = ucp->uc_mcontext.mc_ecx; 704 regs->tf_rax = ucp->uc_mcontext.mc_eax; 705 regs->tf_trapno = ucp->uc_mcontext.mc_trapno; 706 regs->tf_err = ucp->uc_mcontext.mc_err; 707 regs->tf_rip = ucp->uc_mcontext.mc_eip; 708 regs->tf_cs = cs; 709 regs->tf_rflags = ucp->uc_mcontext.mc_eflags; 710 regs->tf_rsp = ucp->uc_mcontext.mc_esp; 711 regs->tf_ss = ucp->uc_mcontext.mc_ss; 712 regs->tf_ds = ucp->uc_mcontext.mc_ds; 713 regs->tf_es = ucp->uc_mcontext.mc_es; 714 regs->tf_fs = ucp->uc_mcontext.mc_fs; 715 regs->tf_gs = ucp->uc_mcontext.mc_gs; 716 regs->tf_flags = TF_HASSEGS; 717 718 kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0); 719 set_pcb_flags(td->td_pcb, PCB_FULL_IRET); 720 return (EJUSTRETURN); 721 } 722 723 /* 724 * Clear registers on exec 725 */ 726 void 727 ia32_setregs(struct thread *td, struct image_params *imgp, u_long stack) 728 { 729 struct trapframe *regs = td->td_frame; 730 struct pcb *pcb = td->td_pcb; 731 732 mtx_lock(&dt_lock); 733 if (td->td_proc->p_md.md_ldt != NULL) 734 user_ldt_free(td); 735 else 736 mtx_unlock(&dt_lock); 737 738 pcb->pcb_fsbase = 0; 739 pcb->pcb_gsbase = 0; 740 pcb->pcb_initial_fpucw = __INITIAL_FPUCW_I386__; 741 742 bzero((char *)regs, sizeof(struct trapframe)); 743 regs->tf_rip = imgp->entry_addr; 744 regs->tf_rsp = stack; 745 regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T); 746 regs->tf_ss = _udatasel; 747 regs->tf_cs = _ucode32sel; 748 regs->tf_rbx = imgp->ps_strings; 749 regs->tf_ds = _udatasel; 750 regs->tf_es = _udatasel; 751 regs->tf_fs = _ufssel; 752 regs->tf_gs = _ugssel; 753 regs->tf_flags = TF_HASSEGS; 754 755 fpstate_drop(td); 756 757 /* Return via doreti so that we can change to a different %cs */ 758 set_pcb_flags(pcb, PCB_32BIT | PCB_FULL_IRET); 759 clear_pcb_flags(pcb, PCB_GS32BIT); 760 td->td_retval[1] = 0; 761 } 762