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/sysctl.h> 59 #include <sys/sysent.h> 60 #include <sys/vnode.h> 61 62 #include <vm/vm.h> 63 #include <vm/vm_kern.h> 64 #include <vm/vm_param.h> 65 #include <vm/pmap.h> 66 #include <vm/vm_map.h> 67 #include <vm/vm_object.h> 68 #include <vm/vm_extern.h> 69 70 #include <compat/freebsd32/freebsd32_util.h> 71 #include <compat/freebsd32/freebsd32_proto.h> 72 #include <compat/ia32/ia32_signal.h> 73 #include <machine/psl.h> 74 #include <machine/segments.h> 75 #include <machine/specialreg.h> 76 #include <machine/frame.h> 77 #include <machine/md_var.h> 78 #include <machine/pcb.h> 79 #include <machine/cpufunc.h> 80 81 #ifdef COMPAT_FREEBSD4 82 static void freebsd4_ia32_sendsig(sig_t, int, sigset_t *, u_long); 83 #endif 84 static void ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp); 85 static int ia32_set_fpcontext(struct thread *td, const struct ia32_mcontext *mcp); 86 87 extern int _ucode32sel, _udatasel; 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 struct savefpu *addr; 96 97 /* 98 * XXX mc_fpstate might be misaligned, since its declaration is not 99 * unportabilized using __attribute__((aligned(16))) like the 100 * declaration of struct savemm, and anyway, alignment doesn't work 101 * for auto variables since we don't use gcc's pessimal stack 102 * alignment. Work around this by abusing the spare fields after 103 * mcp->mc_fpstate. 104 * 105 * XXX unpessimize most cases by only aligning when fxsave might be 106 * called, although this requires knowing too much about 107 * fpugetregs()'s internals. 108 */ 109 addr = (struct savefpu *)&mcp->mc_fpstate; 110 if (td == PCPU_GET(fpcurthread) && ((uintptr_t)(void *)addr & 0xF)) { 111 do 112 addr = (void *)((char *)addr + 4); 113 while ((uintptr_t)(void *)addr & 0xF); 114 } 115 mcp->mc_ownedfp = fpugetregs(td, addr); 116 if (addr != (struct savefpu *)&mcp->mc_fpstate) { 117 bcopy(addr, &mcp->mc_fpstate, sizeof(mcp->mc_fpstate)); 118 bzero(&mcp->mc_spare2, sizeof(mcp->mc_spare2)); 119 } 120 mcp->mc_fpformat = fpuformat(); 121 } 122 123 static int 124 ia32_set_fpcontext(struct thread *td, const struct ia32_mcontext *mcp) 125 { 126 struct savefpu *addr; 127 128 if (mcp->mc_fpformat == _MC_FPFMT_NODEV) 129 return (0); 130 else if (mcp->mc_fpformat != _MC_FPFMT_XMM) 131 return (EINVAL); 132 else if (mcp->mc_ownedfp == _MC_FPOWNED_NONE) 133 /* We don't care what state is left in the FPU or PCB. */ 134 fpstate_drop(td); 135 else if (mcp->mc_ownedfp == _MC_FPOWNED_FPU || 136 mcp->mc_ownedfp == _MC_FPOWNED_PCB) { 137 /* XXX align as above. */ 138 addr = (struct savefpu *)&mcp->mc_fpstate; 139 if (td == PCPU_GET(fpcurthread) && 140 ((uintptr_t)(void *)addr & 0xF)) { 141 do 142 addr = (void *)((char *)addr + 4); 143 while ((uintptr_t)(void *)addr & 0xF); 144 bcopy(&mcp->mc_fpstate, addr, sizeof(mcp->mc_fpstate)); 145 } 146 /* 147 * XXX we violate the dubious requirement that fpusetregs() 148 * be called with interrupts disabled. 149 */ 150 fpusetregs(td, addr); 151 /* 152 * Don't bother putting things back where they were in the 153 * misaligned case, since we know that the caller won't use 154 * them again. 155 */ 156 } else 157 return (EINVAL); 158 return (0); 159 } 160 161 /* 162 * Send an interrupt to process. 163 * 164 * Stack is set up to allow sigcode stored 165 * at top to call routine, followed by kcall 166 * to sigreturn routine below. After sigreturn 167 * resets the signal mask, the stack, and the 168 * frame pointer, it returns to the user 169 * specified pc, psl. 170 */ 171 #ifdef COMPAT_FREEBSD4 172 static void 173 freebsd4_ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 174 { 175 struct ia32_sigframe4 sf, *sfp; 176 struct proc *p; 177 struct thread *td; 178 struct sigacts *psp; 179 struct trapframe *regs; 180 int oonstack; 181 182 td = curthread; 183 p = td->td_proc; 184 PROC_LOCK_ASSERT(p, MA_OWNED); 185 psp = p->p_sigacts; 186 mtx_assert(&psp->ps_mtx, MA_OWNED); 187 regs = td->td_frame; 188 oonstack = sigonstack(regs->tf_rsp); 189 190 /* Save user context. */ 191 bzero(&sf, sizeof(sf)); 192 sf.sf_uc.uc_sigmask = *mask; 193 sf.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp; 194 sf.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size; 195 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 196 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 197 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 198 sf.sf_uc.uc_mcontext.mc_gs = rgs(); 199 sf.sf_uc.uc_mcontext.mc_fs = rfs(); 200 __asm __volatile("movl %%es,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_es)); 201 __asm __volatile("movl %%ds,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_ds)); 202 sf.sf_uc.uc_mcontext.mc_edi = regs->tf_rdi; 203 sf.sf_uc.uc_mcontext.mc_esi = regs->tf_rsi; 204 sf.sf_uc.uc_mcontext.mc_ebp = regs->tf_rbp; 205 sf.sf_uc.uc_mcontext.mc_isp = regs->tf_rsp; /* XXX */ 206 sf.sf_uc.uc_mcontext.mc_ebx = regs->tf_rbx; 207 sf.sf_uc.uc_mcontext.mc_edx = regs->tf_rdx; 208 sf.sf_uc.uc_mcontext.mc_ecx = regs->tf_rcx; 209 sf.sf_uc.uc_mcontext.mc_eax = regs->tf_rax; 210 sf.sf_uc.uc_mcontext.mc_trapno = regs->tf_trapno; 211 sf.sf_uc.uc_mcontext.mc_err = regs->tf_err; 212 sf.sf_uc.uc_mcontext.mc_eip = regs->tf_rip; 213 sf.sf_uc.uc_mcontext.mc_cs = regs->tf_cs; 214 sf.sf_uc.uc_mcontext.mc_eflags = regs->tf_rflags; 215 sf.sf_uc.uc_mcontext.mc_esp = regs->tf_rsp; 216 sf.sf_uc.uc_mcontext.mc_ss = regs->tf_ss; 217 218 /* Allocate space for the signal handler context. */ 219 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 220 SIGISMEMBER(psp->ps_sigonstack, sig)) { 221 sfp = (struct ia32_sigframe4 *)(td->td_sigstk.ss_sp + 222 td->td_sigstk.ss_size - sizeof(sf)); 223 } else 224 sfp = (struct ia32_sigframe4 *)regs->tf_rsp - 1; 225 PROC_UNLOCK(p); 226 227 /* Translate the signal if appropriate. */ 228 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 229 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 230 231 /* Build the argument list for the signal handler. */ 232 sf.sf_signum = sig; 233 sf.sf_ucontext = (register_t)&sfp->sf_uc; 234 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 235 /* Signal handler installed with SA_SIGINFO. */ 236 sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si; 237 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 238 239 /* Fill in POSIX parts */ 240 sf.sf_si.si_signo = sig; 241 sf.sf_si.si_code = code; 242 sf.sf_si.si_addr = regs->tf_addr; 243 } else { 244 /* Old FreeBSD-style arguments. */ 245 sf.sf_siginfo = code; 246 sf.sf_addr = regs->tf_addr; 247 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 248 } 249 mtx_unlock(&psp->ps_mtx); 250 251 /* 252 * Copy the sigframe out to the user's stack. 253 */ 254 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { 255 #ifdef DEBUG 256 printf("process %ld has trashed its stack\n", (long)p->p_pid); 257 #endif 258 PROC_LOCK(p); 259 sigexit(td, SIGILL); 260 } 261 262 regs->tf_rsp = (uintptr_t)sfp; 263 regs->tf_rip = FREEBSD32_PS_STRINGS - sz_freebsd4_ia32_sigcode; 264 regs->tf_rflags &= ~PSL_T; 265 regs->tf_cs = _ucode32sel; 266 regs->tf_ss = _udatasel; 267 load_ds(_udatasel); 268 td->td_pcb->pcb_ds = _udatasel; 269 load_es(_udatasel); 270 td->td_pcb->pcb_es = _udatasel; 271 /* leave user %fs and %gs untouched */ 272 PROC_LOCK(p); 273 mtx_lock(&psp->ps_mtx); 274 } 275 #endif /* COMPAT_FREEBSD4 */ 276 277 void 278 ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 279 { 280 struct ia32_sigframe sf, *sfp; 281 struct proc *p; 282 struct thread *td; 283 struct sigacts *psp; 284 char *sp; 285 struct trapframe *regs; 286 int oonstack; 287 288 td = curthread; 289 p = td->td_proc; 290 PROC_LOCK_ASSERT(p, MA_OWNED); 291 psp = p->p_sigacts; 292 #ifdef COMPAT_FREEBSD4 293 if (SIGISMEMBER(psp->ps_freebsd4, sig)) { 294 freebsd4_ia32_sendsig(catcher, sig, mask, code); 295 return; 296 } 297 #endif 298 mtx_assert(&psp->ps_mtx, MA_OWNED); 299 regs = td->td_frame; 300 oonstack = sigonstack(regs->tf_rsp); 301 302 /* Save user context. */ 303 bzero(&sf, sizeof(sf)); 304 sf.sf_uc.uc_sigmask = *mask; 305 sf.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp; 306 sf.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size; 307 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 308 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 309 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 310 sf.sf_uc.uc_mcontext.mc_gs = rgs(); 311 sf.sf_uc.uc_mcontext.mc_fs = rfs(); 312 __asm __volatile("movl %%es,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_es)); 313 __asm __volatile("movl %%ds,%0" : "=rm" (sf.sf_uc.uc_mcontext.mc_ds)); 314 sf.sf_uc.uc_mcontext.mc_edi = regs->tf_rdi; 315 sf.sf_uc.uc_mcontext.mc_esi = regs->tf_rsi; 316 sf.sf_uc.uc_mcontext.mc_ebp = regs->tf_rbp; 317 sf.sf_uc.uc_mcontext.mc_isp = regs->tf_rsp; /* XXX */ 318 sf.sf_uc.uc_mcontext.mc_ebx = regs->tf_rbx; 319 sf.sf_uc.uc_mcontext.mc_edx = regs->tf_rdx; 320 sf.sf_uc.uc_mcontext.mc_ecx = regs->tf_rcx; 321 sf.sf_uc.uc_mcontext.mc_eax = regs->tf_rax; 322 sf.sf_uc.uc_mcontext.mc_trapno = regs->tf_trapno; 323 sf.sf_uc.uc_mcontext.mc_err = regs->tf_err; 324 sf.sf_uc.uc_mcontext.mc_eip = regs->tf_rip; 325 sf.sf_uc.uc_mcontext.mc_cs = regs->tf_cs; 326 sf.sf_uc.uc_mcontext.mc_eflags = regs->tf_rflags; 327 sf.sf_uc.uc_mcontext.mc_esp = regs->tf_rsp; 328 sf.sf_uc.uc_mcontext.mc_ss = regs->tf_ss; 329 sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); /* magic */ 330 ia32_get_fpcontext(td, &sf.sf_uc.uc_mcontext); 331 fpstate_drop(td); 332 333 /* Allocate space for the signal handler context. */ 334 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 335 SIGISMEMBER(psp->ps_sigonstack, sig)) { 336 sp = td->td_sigstk.ss_sp + 337 td->td_sigstk.ss_size - sizeof(sf); 338 } else 339 sp = (char *)regs->tf_rsp - sizeof(sf); 340 /* Align to 16 bytes. */ 341 sfp = (struct ia32_sigframe *)((uintptr_t)sp & ~0xF); 342 PROC_UNLOCK(p); 343 344 /* Translate the signal if appropriate. */ 345 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 346 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 347 348 /* Build the argument list for the signal handler. */ 349 sf.sf_signum = sig; 350 sf.sf_ucontext = (register_t)&sfp->sf_uc; 351 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 352 /* Signal handler installed with SA_SIGINFO. */ 353 sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si; 354 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 355 356 /* Fill in POSIX parts */ 357 sf.sf_si.si_signo = sig; 358 sf.sf_si.si_code = code; 359 sf.sf_si.si_addr = regs->tf_addr; 360 } else { 361 /* Old FreeBSD-style arguments. */ 362 sf.sf_siginfo = code; 363 sf.sf_addr = regs->tf_addr; 364 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 365 } 366 mtx_unlock(&psp->ps_mtx); 367 368 /* 369 * Copy the sigframe out to the user's stack. 370 */ 371 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { 372 #ifdef DEBUG 373 printf("process %ld has trashed its stack\n", (long)p->p_pid); 374 #endif 375 PROC_LOCK(p); 376 sigexit(td, SIGILL); 377 } 378 379 regs->tf_rsp = (uintptr_t)sfp; 380 regs->tf_rip = FREEBSD32_PS_STRINGS - *(p->p_sysent->sv_szsigcode); 381 regs->tf_rflags &= ~PSL_T; 382 regs->tf_cs = _ucode32sel; 383 regs->tf_ss = _udatasel; 384 load_ds(_udatasel); 385 td->td_pcb->pcb_ds = _udatasel; 386 load_es(_udatasel); 387 td->td_pcb->pcb_es = _udatasel; 388 /* leave user %fs and %gs untouched */ 389 PROC_LOCK(p); 390 mtx_lock(&psp->ps_mtx); 391 } 392 393 /* 394 * System call to cleanup state after a signal 395 * has been taken. Reset signal mask and 396 * stack state from context left by sendsig (above). 397 * Return to previous pc and psl as specified by 398 * context left by sendsig. Check carefully to 399 * make sure that the user has not modified the 400 * state to gain improper privileges. 401 */ 402 #ifdef COMPAT_FREEBSD4 403 /* 404 * MPSAFE 405 */ 406 int 407 freebsd4_freebsd32_sigreturn(td, uap) 408 struct thread *td; 409 struct freebsd4_freebsd32_sigreturn_args /* { 410 const struct freebsd4_freebsd32_ucontext *sigcntxp; 411 } */ *uap; 412 { 413 struct ia32_ucontext4 uc; 414 struct proc *p = td->td_proc; 415 struct trapframe *regs; 416 const struct ia32_ucontext4 *ucp; 417 int cs, eflags, error; 418 419 error = copyin(uap->sigcntxp, &uc, sizeof(uc)); 420 if (error != 0) 421 return (error); 422 ucp = &uc; 423 regs = td->td_frame; 424 eflags = ucp->uc_mcontext.mc_eflags; 425 /* 426 * Don't allow users to change privileged or reserved flags. 427 */ 428 /* 429 * XXX do allow users to change the privileged flag PSL_RF. 430 * The cpu sets PSL_RF in tf_eflags for faults. Debuggers 431 * should sometimes set it there too. tf_eflags is kept in 432 * the signal context during signal handling and there is no 433 * other place to remember it, so the PSL_RF bit may be 434 * corrupted by the signal handler without us knowing. 435 * Corruption of the PSL_RF bit at worst causes one more or 436 * one less debugger trap, so allowing it is fairly harmless. 437 */ 438 if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) { 439 printf("freebsd4_freebsd32_sigreturn: eflags = 0x%x\n", eflags); 440 return (EINVAL); 441 } 442 443 /* 444 * Don't allow users to load a valid privileged %cs. Let the 445 * hardware check for invalid selectors, excess privilege in 446 * other selectors, invalid %eip's and invalid %esp's. 447 */ 448 cs = ucp->uc_mcontext.mc_cs; 449 if (!CS_SECURE(cs)) { 450 printf("freebsd4_sigreturn: cs = 0x%x\n", cs); 451 trapsignal(td, SIGBUS, T_PROTFLT); 452 return (EINVAL); 453 } 454 455 /* Segment selectors restored by sigtramp.S */ 456 regs->tf_rdi = ucp->uc_mcontext.mc_edi; 457 regs->tf_rsi = ucp->uc_mcontext.mc_esi; 458 regs->tf_rbp = ucp->uc_mcontext.mc_ebp; 459 regs->tf_rbx = ucp->uc_mcontext.mc_ebx; 460 regs->tf_rdx = ucp->uc_mcontext.mc_edx; 461 regs->tf_rcx = ucp->uc_mcontext.mc_ecx; 462 regs->tf_rax = ucp->uc_mcontext.mc_eax; 463 regs->tf_trapno = ucp->uc_mcontext.mc_trapno; 464 regs->tf_err = ucp->uc_mcontext.mc_err; 465 regs->tf_rip = ucp->uc_mcontext.mc_eip; 466 regs->tf_cs = cs; 467 regs->tf_rflags = ucp->uc_mcontext.mc_eflags; 468 regs->tf_rsp = ucp->uc_mcontext.mc_esp; 469 regs->tf_ss = ucp->uc_mcontext.mc_ss; 470 471 PROC_LOCK(p); 472 td->td_sigmask = ucp->uc_sigmask; 473 SIG_CANTMASK(td->td_sigmask); 474 signotify(td); 475 PROC_UNLOCK(p); 476 return (EJUSTRETURN); 477 } 478 #endif /* COMPAT_FREEBSD4 */ 479 480 /* 481 * MPSAFE 482 */ 483 int 484 freebsd32_sigreturn(td, uap) 485 struct thread *td; 486 struct freebsd32_sigreturn_args /* { 487 const struct freebsd32_ucontext *sigcntxp; 488 } */ *uap; 489 { 490 struct ia32_ucontext uc; 491 struct proc *p = td->td_proc; 492 struct trapframe *regs; 493 const struct ia32_ucontext *ucp; 494 int cs, eflags, error, ret; 495 496 error = copyin(uap->sigcntxp, &uc, sizeof(uc)); 497 if (error != 0) 498 return (error); 499 ucp = &uc; 500 regs = td->td_frame; 501 eflags = ucp->uc_mcontext.mc_eflags; 502 /* 503 * Don't allow users to change privileged or reserved flags. 504 */ 505 /* 506 * XXX do allow users to change the privileged flag PSL_RF. 507 * The cpu sets PSL_RF in tf_eflags for faults. Debuggers 508 * should sometimes set it there too. tf_eflags is kept in 509 * the signal context during signal handling and there is no 510 * other place to remember it, so the PSL_RF bit may be 511 * corrupted by the signal handler without us knowing. 512 * Corruption of the PSL_RF bit at worst causes one more or 513 * one less debugger trap, so allowing it is fairly harmless. 514 */ 515 if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) { 516 printf("freebsd32_sigreturn: eflags = 0x%x\n", eflags); 517 return (EINVAL); 518 } 519 520 /* 521 * Don't allow users to load a valid privileged %cs. Let the 522 * hardware check for invalid selectors, excess privilege in 523 * other selectors, invalid %eip's and invalid %esp's. 524 */ 525 cs = ucp->uc_mcontext.mc_cs; 526 if (!CS_SECURE(cs)) { 527 printf("sigreturn: cs = 0x%x\n", cs); 528 trapsignal(td, SIGBUS, T_PROTFLT); 529 return (EINVAL); 530 } 531 532 ret = ia32_set_fpcontext(td, &ucp->uc_mcontext); 533 if (ret != 0) 534 return (ret); 535 536 /* Segment selectors restored by sigtramp.S */ 537 regs->tf_rdi = ucp->uc_mcontext.mc_edi; 538 regs->tf_rsi = ucp->uc_mcontext.mc_esi; 539 regs->tf_rbp = ucp->uc_mcontext.mc_ebp; 540 regs->tf_rbx = ucp->uc_mcontext.mc_ebx; 541 regs->tf_rdx = ucp->uc_mcontext.mc_edx; 542 regs->tf_rcx = ucp->uc_mcontext.mc_ecx; 543 regs->tf_rax = ucp->uc_mcontext.mc_eax; 544 regs->tf_trapno = ucp->uc_mcontext.mc_trapno; 545 regs->tf_err = ucp->uc_mcontext.mc_err; 546 regs->tf_rip = ucp->uc_mcontext.mc_eip; 547 regs->tf_cs = cs; 548 regs->tf_rflags = ucp->uc_mcontext.mc_eflags; 549 regs->tf_rsp = ucp->uc_mcontext.mc_esp; 550 regs->tf_ss = ucp->uc_mcontext.mc_ss; 551 552 PROC_LOCK(p); 553 td->td_sigmask = ucp->uc_sigmask; 554 SIG_CANTMASK(td->td_sigmask); 555 signotify(td); 556 PROC_UNLOCK(p); 557 return (EJUSTRETURN); 558 } 559 560 /* 561 * Clear registers on exec 562 */ 563 void 564 ia32_setregs(td, entry, stack, ps_strings) 565 struct thread *td; 566 u_long entry; 567 u_long stack; 568 u_long ps_strings; 569 { 570 struct trapframe *regs = td->td_frame; 571 struct pcb *pcb = td->td_pcb; 572 573 wrmsr(MSR_FSBASE, 0); 574 wrmsr(MSR_KGSBASE, 0); /* User value while we're in the kernel */ 575 pcb->pcb_fsbase = 0; 576 pcb->pcb_gsbase = 0; 577 load_ds(_udatasel); 578 load_es(_udatasel); 579 load_fs(_udatasel); 580 load_gs(_udatasel); 581 pcb->pcb_ds = _udatasel; 582 pcb->pcb_es = _udatasel; 583 pcb->pcb_fs = _udatasel; 584 pcb->pcb_gs = _udatasel; 585 586 bzero((char *)regs, sizeof(struct trapframe)); 587 regs->tf_rip = entry; 588 regs->tf_rsp = stack; 589 regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T); 590 regs->tf_ss = _udatasel; 591 regs->tf_cs = _ucode32sel; 592 regs->tf_rbx = ps_strings; 593 load_cr0(rcr0() | CR0_MP | CR0_TS); 594 fpstate_drop(td); 595 596 /* Return via doreti so that we can change to a different %cs */ 597 pcb->pcb_flags |= PCB_FULLCTX; 598 td->td_retval[1] = 0; 599 } 600