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 304 #ifdef COMPAT_43 305 static void 306 ia32_osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 307 { 308 struct ia32_sigframe3 sf, *fp; 309 struct proc *p; 310 struct thread *td; 311 struct sigacts *psp; 312 struct trapframe *regs; 313 int sig; 314 int oonstack; 315 316 td = curthread; 317 p = td->td_proc; 318 PROC_LOCK_ASSERT(p, MA_OWNED); 319 sig = ksi->ksi_signo; 320 psp = p->p_sigacts; 321 mtx_assert(&psp->ps_mtx, MA_OWNED); 322 regs = td->td_frame; 323 oonstack = sigonstack(regs->tf_rsp); 324 325 /* Allocate space for the signal handler context. */ 326 if ((td->td_pflags & TDP_ALTSTACK) && !oonstack && 327 SIGISMEMBER(psp->ps_sigonstack, sig)) { 328 fp = (struct ia32_sigframe3 *)(td->td_sigstk.ss_sp + 329 td->td_sigstk.ss_size - sizeof(sf)); 330 td->td_sigstk.ss_flags |= SS_ONSTACK; 331 } else 332 fp = (struct ia32_sigframe3 *)regs->tf_rsp - 1; 333 334 /* Translate the signal if appropriate. */ 335 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 336 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 337 338 /* Build the argument list for the signal handler. */ 339 sf.sf_signum = sig; 340 sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc; 341 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 342 /* Signal handler installed with SA_SIGINFO. */ 343 sf.sf_arg2 = (register_t)&fp->sf_siginfo; 344 sf.sf_siginfo.si_signo = sig; 345 sf.sf_siginfo.si_code = ksi->ksi_code; 346 sf.sf_ah = (uintptr_t)catcher; 347 } else { 348 /* Old FreeBSD-style arguments. */ 349 sf.sf_arg2 = ksi->ksi_code; 350 sf.sf_addr = (register_t)ksi->ksi_addr; 351 sf.sf_ah = (uintptr_t)catcher; 352 } 353 mtx_unlock(&psp->ps_mtx); 354 PROC_UNLOCK(p); 355 356 /* Save most if not all of trap frame. */ 357 sf.sf_siginfo.si_sc.sc_eax = regs->tf_rax; 358 sf.sf_siginfo.si_sc.sc_ebx = regs->tf_rbx; 359 sf.sf_siginfo.si_sc.sc_ecx = regs->tf_rcx; 360 sf.sf_siginfo.si_sc.sc_edx = regs->tf_rdx; 361 sf.sf_siginfo.si_sc.sc_esi = regs->tf_rsi; 362 sf.sf_siginfo.si_sc.sc_edi = regs->tf_rdi; 363 sf.sf_siginfo.si_sc.sc_cs = regs->tf_cs; 364 sf.sf_siginfo.si_sc.sc_ds = regs->tf_ds; 365 sf.sf_siginfo.si_sc.sc_ss = regs->tf_ss; 366 sf.sf_siginfo.si_sc.sc_es = regs->tf_es; 367 sf.sf_siginfo.si_sc.sc_fs = regs->tf_fs; 368 sf.sf_siginfo.si_sc.sc_gs = regs->tf_gs; 369 sf.sf_siginfo.si_sc.sc_isp = regs->tf_rsp; 370 371 /* Build the signal context to be used by osigreturn(). */ 372 sf.sf_siginfo.si_sc.sc_onstack = (oonstack) ? 1 : 0; 373 SIG2OSIG(*mask, sf.sf_siginfo.si_sc.sc_mask); 374 sf.sf_siginfo.si_sc.sc_esp = regs->tf_rsp; 375 sf.sf_siginfo.si_sc.sc_ebp = regs->tf_rbp; 376 sf.sf_siginfo.si_sc.sc_eip = regs->tf_rip; 377 sf.sf_siginfo.si_sc.sc_eflags = regs->tf_rflags; 378 sf.sf_siginfo.si_sc.sc_trapno = regs->tf_trapno; 379 sf.sf_siginfo.si_sc.sc_err = regs->tf_err; 380 381 /* 382 * Copy the sigframe out to the user's stack. 383 */ 384 if (copyout(&sf, fp, sizeof(*fp)) != 0) { 385 #ifdef DEBUG 386 printf("process %ld has trashed its stack\n", (long)p->p_pid); 387 #endif 388 PROC_LOCK(p); 389 sigexit(td, SIGILL); 390 } 391 392 regs->tf_rsp = (uintptr_t)fp; 393 regs->tf_rip = p->p_sysent->sv_psstrings - sz_ia32_osigcode; 394 regs->tf_rflags &= ~(PSL_T | PSL_D); 395 regs->tf_cs = _ucode32sel; 396 regs->tf_ds = _udatasel; 397 regs->tf_es = _udatasel; 398 regs->tf_fs = _udatasel; 399 regs->tf_ss = _udatasel; 400 set_pcb_flags(td->td_pcb, PCB_FULL_IRET); 401 PROC_LOCK(p); 402 mtx_lock(&psp->ps_mtx); 403 } 404 #endif 405 406 #ifdef COMPAT_FREEBSD4 407 static void 408 freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 409 { 410 struct ia32_sigframe4 sf, *sfp; 411 struct siginfo32 siginfo; 412 struct proc *p; 413 struct thread *td; 414 struct sigacts *psp; 415 struct trapframe *regs; 416 int oonstack; 417 int sig; 418 419 td = curthread; 420 p = td->td_proc; 421 siginfo_to_siginfo32(&ksi->ksi_info, &siginfo); 422 423 PROC_LOCK_ASSERT(p, MA_OWNED); 424 sig = siginfo.si_signo; 425 psp = p->p_sigacts; 426 mtx_assert(&psp->ps_mtx, MA_OWNED); 427 regs = td->td_frame; 428 oonstack = sigonstack(regs->tf_rsp); 429 430 /* Save user context. */ 431 bzero(&sf, sizeof(sf)); 432 sf.sf_uc.uc_sigmask = *mask; 433 sf.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp; 434 sf.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size; 435 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 436 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 437 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 438 sf.sf_uc.uc_mcontext.mc_edi = regs->tf_rdi; 439 sf.sf_uc.uc_mcontext.mc_esi = regs->tf_rsi; 440 sf.sf_uc.uc_mcontext.mc_ebp = regs->tf_rbp; 441 sf.sf_uc.uc_mcontext.mc_isp = regs->tf_rsp; /* XXX */ 442 sf.sf_uc.uc_mcontext.mc_ebx = regs->tf_rbx; 443 sf.sf_uc.uc_mcontext.mc_edx = regs->tf_rdx; 444 sf.sf_uc.uc_mcontext.mc_ecx = regs->tf_rcx; 445 sf.sf_uc.uc_mcontext.mc_eax = regs->tf_rax; 446 sf.sf_uc.uc_mcontext.mc_trapno = regs->tf_trapno; 447 sf.sf_uc.uc_mcontext.mc_err = regs->tf_err; 448 sf.sf_uc.uc_mcontext.mc_eip = regs->tf_rip; 449 sf.sf_uc.uc_mcontext.mc_cs = regs->tf_cs; 450 sf.sf_uc.uc_mcontext.mc_eflags = regs->tf_rflags; 451 sf.sf_uc.uc_mcontext.mc_esp = regs->tf_rsp; 452 sf.sf_uc.uc_mcontext.mc_ss = regs->tf_ss; 453 sf.sf_uc.uc_mcontext.mc_ds = regs->tf_ds; 454 sf.sf_uc.uc_mcontext.mc_es = regs->tf_es; 455 sf.sf_uc.uc_mcontext.mc_fs = regs->tf_fs; 456 sf.sf_uc.uc_mcontext.mc_gs = regs->tf_gs; 457 bzero(sf.sf_uc.uc_mcontext.mc_fpregs, 458 sizeof(sf.sf_uc.uc_mcontext.mc_fpregs)); 459 bzero(sf.sf_uc.uc_mcontext.__spare__, 460 sizeof(sf.sf_uc.uc_mcontext.__spare__)); 461 bzero(sf.sf_uc.__spare__, sizeof(sf.sf_uc.__spare__)); 462 463 /* Allocate space for the signal handler context. */ 464 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 465 SIGISMEMBER(psp->ps_sigonstack, sig)) { 466 sfp = (struct ia32_sigframe4 *)(td->td_sigstk.ss_sp + 467 td->td_sigstk.ss_size - sizeof(sf)); 468 } else 469 sfp = (struct ia32_sigframe4 *)regs->tf_rsp - 1; 470 PROC_UNLOCK(p); 471 472 /* Translate the signal if appropriate. */ 473 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 474 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 475 476 /* Build the argument list for the signal handler. */ 477 sf.sf_signum = sig; 478 sf.sf_ucontext = (register_t)&sfp->sf_uc; 479 bzero(&sf.sf_si, sizeof(sf.sf_si)); 480 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 481 /* Signal handler installed with SA_SIGINFO. */ 482 sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si; 483 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 484 485 /* Fill in POSIX parts */ 486 sf.sf_si = siginfo; 487 sf.sf_si.si_signo = sig; 488 } else { 489 /* Old FreeBSD-style arguments. */ 490 sf.sf_siginfo = siginfo.si_code; 491 sf.sf_addr = (u_int32_t)siginfo.si_addr; 492 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 493 } 494 mtx_unlock(&psp->ps_mtx); 495 496 /* 497 * Copy the sigframe out to the user's stack. 498 */ 499 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { 500 #ifdef DEBUG 501 printf("process %ld has trashed its stack\n", (long)p->p_pid); 502 #endif 503 PROC_LOCK(p); 504 sigexit(td, SIGILL); 505 } 506 507 regs->tf_rsp = (uintptr_t)sfp; 508 regs->tf_rip = p->p_sysent->sv_sigcode_base + sz_ia32_sigcode - 509 sz_freebsd4_ia32_sigcode; 510 regs->tf_rflags &= ~(PSL_T | PSL_D); 511 regs->tf_cs = _ucode32sel; 512 regs->tf_ss = _udatasel; 513 regs->tf_ds = _udatasel; 514 regs->tf_es = _udatasel; 515 set_pcb_flags(td->td_pcb, PCB_FULL_IRET); 516 /* leave user %fs and %gs untouched */ 517 PROC_LOCK(p); 518 mtx_lock(&psp->ps_mtx); 519 } 520 #endif /* COMPAT_FREEBSD4 */ 521 522 void 523 ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 524 { 525 struct ia32_sigframe sf, *sfp; 526 struct siginfo32 siginfo; 527 struct proc *p; 528 struct thread *td; 529 struct sigacts *psp; 530 char *sp; 531 struct trapframe *regs; 532 int oonstack; 533 int sig; 534 535 siginfo_to_siginfo32(&ksi->ksi_info, &siginfo); 536 td = curthread; 537 p = td->td_proc; 538 PROC_LOCK_ASSERT(p, MA_OWNED); 539 sig = siginfo.si_signo; 540 psp = p->p_sigacts; 541 #ifdef COMPAT_FREEBSD4 542 if (SIGISMEMBER(psp->ps_freebsd4, sig)) { 543 freebsd4_ia32_sendsig(catcher, ksi, mask); 544 return; 545 } 546 #endif 547 #ifdef COMPAT_43 548 if (SIGISMEMBER(psp->ps_osigset, sig)) { 549 ia32_osendsig(catcher, ksi, mask); 550 return; 551 } 552 #endif 553 mtx_assert(&psp->ps_mtx, MA_OWNED); 554 regs = td->td_frame; 555 oonstack = sigonstack(regs->tf_rsp); 556 557 /* Save user context. */ 558 bzero(&sf, sizeof(sf)); 559 sf.sf_uc.uc_sigmask = *mask; 560 sf.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp; 561 sf.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size; 562 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 563 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 564 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 565 sf.sf_uc.uc_mcontext.mc_edi = regs->tf_rdi; 566 sf.sf_uc.uc_mcontext.mc_esi = regs->tf_rsi; 567 sf.sf_uc.uc_mcontext.mc_ebp = regs->tf_rbp; 568 sf.sf_uc.uc_mcontext.mc_isp = regs->tf_rsp; /* XXX */ 569 sf.sf_uc.uc_mcontext.mc_ebx = regs->tf_rbx; 570 sf.sf_uc.uc_mcontext.mc_edx = regs->tf_rdx; 571 sf.sf_uc.uc_mcontext.mc_ecx = regs->tf_rcx; 572 sf.sf_uc.uc_mcontext.mc_eax = regs->tf_rax; 573 sf.sf_uc.uc_mcontext.mc_trapno = regs->tf_trapno; 574 sf.sf_uc.uc_mcontext.mc_err = regs->tf_err; 575 sf.sf_uc.uc_mcontext.mc_eip = regs->tf_rip; 576 sf.sf_uc.uc_mcontext.mc_cs = regs->tf_cs; 577 sf.sf_uc.uc_mcontext.mc_eflags = regs->tf_rflags; 578 sf.sf_uc.uc_mcontext.mc_esp = regs->tf_rsp; 579 sf.sf_uc.uc_mcontext.mc_ss = regs->tf_ss; 580 sf.sf_uc.uc_mcontext.mc_ds = regs->tf_ds; 581 sf.sf_uc.uc_mcontext.mc_es = regs->tf_es; 582 sf.sf_uc.uc_mcontext.mc_fs = regs->tf_fs; 583 sf.sf_uc.uc_mcontext.mc_gs = regs->tf_gs; 584 sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); /* magic */ 585 ia32_get_fpcontext(td, &sf.sf_uc.uc_mcontext); 586 fpstate_drop(td); 587 sf.sf_uc.uc_mcontext.mc_fsbase = td->td_pcb->pcb_fsbase; 588 sf.sf_uc.uc_mcontext.mc_gsbase = td->td_pcb->pcb_gsbase; 589 bzero(sf.sf_uc.__spare__, sizeof(sf.sf_uc.__spare__)); 590 591 /* Allocate space for the signal handler context. */ 592 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 593 SIGISMEMBER(psp->ps_sigonstack, sig)) { 594 sp = td->td_sigstk.ss_sp + 595 td->td_sigstk.ss_size - sizeof(sf); 596 } else 597 sp = (char *)regs->tf_rsp - sizeof(sf); 598 /* Align to 16 bytes. */ 599 sfp = (struct ia32_sigframe *)((uintptr_t)sp & ~0xF); 600 PROC_UNLOCK(p); 601 602 /* Translate the signal if appropriate. */ 603 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 604 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 605 606 /* Build the argument list for the signal handler. */ 607 sf.sf_signum = sig; 608 sf.sf_ucontext = (register_t)&sfp->sf_uc; 609 bzero(&sf.sf_si, sizeof(sf.sf_si)); 610 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 611 /* Signal handler installed with SA_SIGINFO. */ 612 sf.sf_siginfo = (u_int32_t)(uintptr_t)&sfp->sf_si; 613 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 614 615 /* Fill in POSIX parts */ 616 sf.sf_si = siginfo; 617 sf.sf_si.si_signo = sig; 618 } else { 619 /* Old FreeBSD-style arguments. */ 620 sf.sf_siginfo = siginfo.si_code; 621 sf.sf_addr = (u_int32_t)siginfo.si_addr; 622 sf.sf_ah = (u_int32_t)(uintptr_t)catcher; 623 } 624 mtx_unlock(&psp->ps_mtx); 625 626 /* 627 * Copy the sigframe out to the user's stack. 628 */ 629 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { 630 #ifdef DEBUG 631 printf("process %ld has trashed its stack\n", (long)p->p_pid); 632 #endif 633 PROC_LOCK(p); 634 sigexit(td, SIGILL); 635 } 636 637 regs->tf_rsp = (uintptr_t)sfp; 638 regs->tf_rip = p->p_sysent->sv_sigcode_base; 639 regs->tf_rflags &= ~(PSL_T | PSL_D); 640 regs->tf_cs = _ucode32sel; 641 regs->tf_ss = _udatasel; 642 regs->tf_ds = _udatasel; 643 regs->tf_es = _udatasel; 644 set_pcb_flags(td->td_pcb, PCB_FULL_IRET); 645 /* XXXKIB leave user %fs and %gs untouched */ 646 PROC_LOCK(p); 647 mtx_lock(&psp->ps_mtx); 648 } 649 650 /* 651 * System call to cleanup state after a signal 652 * has been taken. Reset signal mask and 653 * stack state from context left by sendsig (above). 654 * Return to previous pc and psl as specified by 655 * context left by sendsig. Check carefully to 656 * make sure that the user has not modified the 657 * state to gain improper privileges. 658 */ 659 660 #ifdef COMPAT_43 661 int 662 ofreebsd32_sigreturn(struct thread *td, struct ofreebsd32_sigreturn_args *uap) 663 { 664 struct ia32_sigcontext3 sc, *scp; 665 struct trapframe *regs; 666 int eflags, error; 667 ksiginfo_t ksi; 668 669 regs = td->td_frame; 670 error = copyin(uap->sigcntxp, &sc, sizeof(sc)); 671 if (error != 0) 672 return (error); 673 scp = ≻ 674 eflags = scp->sc_eflags; 675 if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) { 676 return (EINVAL); 677 } 678 if (!CS_SECURE(scp->sc_cs)) { 679 ksiginfo_init_trap(&ksi); 680 ksi.ksi_signo = SIGBUS; 681 ksi.ksi_code = BUS_OBJERR; 682 ksi.ksi_trapno = T_PROTFLT; 683 ksi.ksi_addr = (void *)regs->tf_rip; 684 trapsignal(td, &ksi); 685 return (EINVAL); 686 } 687 regs->tf_ds = scp->sc_ds; 688 regs->tf_es = scp->sc_es; 689 regs->tf_fs = scp->sc_fs; 690 regs->tf_gs = scp->sc_gs; 691 692 regs->tf_rax = scp->sc_eax; 693 regs->tf_rbx = scp->sc_ebx; 694 regs->tf_rcx = scp->sc_ecx; 695 regs->tf_rdx = scp->sc_edx; 696 regs->tf_rsi = scp->sc_esi; 697 regs->tf_rdi = scp->sc_edi; 698 regs->tf_cs = scp->sc_cs; 699 regs->tf_ss = scp->sc_ss; 700 regs->tf_rbp = scp->sc_ebp; 701 regs->tf_rsp = scp->sc_esp; 702 regs->tf_rip = scp->sc_eip; 703 regs->tf_rflags = eflags; 704 705 if (scp->sc_onstack & 1) 706 td->td_sigstk.ss_flags |= SS_ONSTACK; 707 else 708 td->td_sigstk.ss_flags &= ~SS_ONSTACK; 709 710 kern_sigprocmask(td, SIG_SETMASK, (sigset_t *)&scp->sc_mask, NULL, 711 SIGPROCMASK_OLD); 712 set_pcb_flags(td->td_pcb, PCB_FULL_IRET); 713 return (EJUSTRETURN); 714 } 715 #endif 716 717 #ifdef COMPAT_FREEBSD4 718 /* 719 * MPSAFE 720 */ 721 int 722 freebsd4_freebsd32_sigreturn(td, uap) 723 struct thread *td; 724 struct freebsd4_freebsd32_sigreturn_args /* { 725 const struct freebsd4_freebsd32_ucontext *sigcntxp; 726 } */ *uap; 727 { 728 struct ia32_ucontext4 uc; 729 struct trapframe *regs; 730 struct ia32_ucontext4 *ucp; 731 int cs, eflags, error; 732 ksiginfo_t ksi; 733 734 error = copyin(uap->sigcntxp, &uc, sizeof(uc)); 735 if (error != 0) 736 return (error); 737 ucp = &uc; 738 regs = td->td_frame; 739 eflags = ucp->uc_mcontext.mc_eflags; 740 /* 741 * Don't allow users to change privileged or reserved flags. 742 */ 743 /* 744 * XXX do allow users to change the privileged flag PSL_RF. 745 * The cpu sets PSL_RF in tf_eflags for faults. Debuggers 746 * should sometimes set it there too. tf_eflags is kept in 747 * the signal context during signal handling and there is no 748 * other place to remember it, so the PSL_RF bit may be 749 * corrupted by the signal handler without us knowing. 750 * Corruption of the PSL_RF bit at worst causes one more or 751 * one less debugger trap, so allowing it is fairly harmless. 752 */ 753 if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) { 754 uprintf("pid %d (%s): freebsd4_freebsd32_sigreturn eflags = 0x%x\n", 755 td->td_proc->p_pid, td->td_name, eflags); 756 return (EINVAL); 757 } 758 759 /* 760 * Don't allow users to load a valid privileged %cs. Let the 761 * hardware check for invalid selectors, excess privilege in 762 * other selectors, invalid %eip's and invalid %esp's. 763 */ 764 cs = ucp->uc_mcontext.mc_cs; 765 if (!CS_SECURE(cs)) { 766 uprintf("pid %d (%s): freebsd4_sigreturn cs = 0x%x\n", 767 td->td_proc->p_pid, td->td_name, cs); 768 ksiginfo_init_trap(&ksi); 769 ksi.ksi_signo = SIGBUS; 770 ksi.ksi_code = BUS_OBJERR; 771 ksi.ksi_trapno = T_PROTFLT; 772 ksi.ksi_addr = (void *)regs->tf_rip; 773 trapsignal(td, &ksi); 774 return (EINVAL); 775 } 776 777 regs->tf_rdi = ucp->uc_mcontext.mc_edi; 778 regs->tf_rsi = ucp->uc_mcontext.mc_esi; 779 regs->tf_rbp = ucp->uc_mcontext.mc_ebp; 780 regs->tf_rbx = ucp->uc_mcontext.mc_ebx; 781 regs->tf_rdx = ucp->uc_mcontext.mc_edx; 782 regs->tf_rcx = ucp->uc_mcontext.mc_ecx; 783 regs->tf_rax = ucp->uc_mcontext.mc_eax; 784 regs->tf_trapno = ucp->uc_mcontext.mc_trapno; 785 regs->tf_err = ucp->uc_mcontext.mc_err; 786 regs->tf_rip = ucp->uc_mcontext.mc_eip; 787 regs->tf_cs = cs; 788 regs->tf_rflags = ucp->uc_mcontext.mc_eflags; 789 regs->tf_rsp = ucp->uc_mcontext.mc_esp; 790 regs->tf_ss = ucp->uc_mcontext.mc_ss; 791 regs->tf_ds = ucp->uc_mcontext.mc_ds; 792 regs->tf_es = ucp->uc_mcontext.mc_es; 793 regs->tf_fs = ucp->uc_mcontext.mc_fs; 794 regs->tf_gs = ucp->uc_mcontext.mc_gs; 795 796 kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0); 797 set_pcb_flags(td->td_pcb, PCB_FULL_IRET); 798 return (EJUSTRETURN); 799 } 800 #endif /* COMPAT_FREEBSD4 */ 801 802 /* 803 * MPSAFE 804 */ 805 int 806 freebsd32_sigreturn(td, uap) 807 struct thread *td; 808 struct freebsd32_sigreturn_args /* { 809 const struct freebsd32_ucontext *sigcntxp; 810 } */ *uap; 811 { 812 struct ia32_ucontext uc; 813 struct trapframe *regs; 814 struct ia32_ucontext *ucp; 815 int cs, eflags, error, ret; 816 ksiginfo_t ksi; 817 818 error = copyin(uap->sigcntxp, &uc, sizeof(uc)); 819 if (error != 0) 820 return (error); 821 ucp = &uc; 822 regs = td->td_frame; 823 eflags = ucp->uc_mcontext.mc_eflags; 824 /* 825 * Don't allow users to change privileged or reserved flags. 826 */ 827 /* 828 * XXX do allow users to change the privileged flag PSL_RF. 829 * The cpu sets PSL_RF in tf_eflags for faults. Debuggers 830 * should sometimes set it there too. tf_eflags is kept in 831 * the signal context during signal handling and there is no 832 * other place to remember it, so the PSL_RF bit may be 833 * corrupted by the signal handler without us knowing. 834 * Corruption of the PSL_RF bit at worst causes one more or 835 * one less debugger trap, so allowing it is fairly harmless. 836 */ 837 if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) { 838 uprintf("pid %d (%s): freebsd32_sigreturn eflags = 0x%x\n", 839 td->td_proc->p_pid, td->td_name, eflags); 840 return (EINVAL); 841 } 842 843 /* 844 * Don't allow users to load a valid privileged %cs. Let the 845 * hardware check for invalid selectors, excess privilege in 846 * other selectors, invalid %eip's and invalid %esp's. 847 */ 848 cs = ucp->uc_mcontext.mc_cs; 849 if (!CS_SECURE(cs)) { 850 uprintf("pid %d (%s): sigreturn cs = 0x%x\n", 851 td->td_proc->p_pid, td->td_name, cs); 852 ksiginfo_init_trap(&ksi); 853 ksi.ksi_signo = SIGBUS; 854 ksi.ksi_code = BUS_OBJERR; 855 ksi.ksi_trapno = T_PROTFLT; 856 ksi.ksi_addr = (void *)regs->tf_rip; 857 trapsignal(td, &ksi); 858 return (EINVAL); 859 } 860 861 ret = ia32_set_fpcontext(td, &ucp->uc_mcontext); 862 if (ret != 0) 863 return (ret); 864 865 regs->tf_rdi = ucp->uc_mcontext.mc_edi; 866 regs->tf_rsi = ucp->uc_mcontext.mc_esi; 867 regs->tf_rbp = ucp->uc_mcontext.mc_ebp; 868 regs->tf_rbx = ucp->uc_mcontext.mc_ebx; 869 regs->tf_rdx = ucp->uc_mcontext.mc_edx; 870 regs->tf_rcx = ucp->uc_mcontext.mc_ecx; 871 regs->tf_rax = ucp->uc_mcontext.mc_eax; 872 regs->tf_trapno = ucp->uc_mcontext.mc_trapno; 873 regs->tf_err = ucp->uc_mcontext.mc_err; 874 regs->tf_rip = ucp->uc_mcontext.mc_eip; 875 regs->tf_cs = cs; 876 regs->tf_rflags = ucp->uc_mcontext.mc_eflags; 877 regs->tf_rsp = ucp->uc_mcontext.mc_esp; 878 regs->tf_ss = ucp->uc_mcontext.mc_ss; 879 regs->tf_ds = ucp->uc_mcontext.mc_ds; 880 regs->tf_es = ucp->uc_mcontext.mc_es; 881 regs->tf_fs = ucp->uc_mcontext.mc_fs; 882 regs->tf_gs = ucp->uc_mcontext.mc_gs; 883 regs->tf_flags = TF_HASSEGS; 884 885 kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0); 886 set_pcb_flags(td->td_pcb, PCB_FULL_IRET); 887 return (EJUSTRETURN); 888 } 889 890 /* 891 * Clear registers on exec 892 */ 893 void 894 ia32_setregs(struct thread *td, struct image_params *imgp, u_long stack) 895 { 896 struct trapframe *regs = td->td_frame; 897 struct pcb *pcb = td->td_pcb; 898 899 mtx_lock(&dt_lock); 900 if (td->td_proc->p_md.md_ldt != NULL) 901 user_ldt_free(td); 902 else 903 mtx_unlock(&dt_lock); 904 #ifdef COMPAT_43 905 setup_lcall_gate(); 906 #endif 907 908 pcb->pcb_fsbase = 0; 909 pcb->pcb_gsbase = 0; 910 pcb->pcb_initial_fpucw = __INITIAL_FPUCW_I386__; 911 912 bzero((char *)regs, sizeof(struct trapframe)); 913 regs->tf_rip = imgp->entry_addr; 914 regs->tf_rsp = stack; 915 regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T); 916 regs->tf_ss = _udatasel; 917 regs->tf_cs = _ucode32sel; 918 regs->tf_rbx = imgp->ps_strings; 919 regs->tf_ds = _udatasel; 920 regs->tf_es = _udatasel; 921 regs->tf_fs = _ufssel; 922 regs->tf_gs = _ugssel; 923 regs->tf_flags = TF_HASSEGS; 924 925 fpstate_drop(td); 926 927 /* Return via doreti so that we can change to a different %cs */ 928 set_pcb_flags(pcb, PCB_32BIT | PCB_FULL_IRET); 929 clear_pcb_flags(pcb, PCB_GS32BIT); 930 td->td_retval[1] = 0; 931 } 932