int darwin_sys_sigprocmask(struct lwp *l, const struct darwin_sys_sigprocmask_args *uap, register_t *retval) { /* { syscallarg(int) how; syscallarg(sigset13_t *) set; syscallarg(sigset13_t *) oset; } */ int error; sigset13_t kdset; sigset_t kbset, kboset; if (SCARG(uap, set) != NULL) { error = copyin(SCARG(uap, set), &kdset, sizeof(kdset)); if (error != 0) return error; native_sigset13_to_sigset(&kdset, &kbset); error = sigprocmask1(l, SCARG(uap, how), &kbset, &kboset); } else error = sigprocmask1(l, SCARG(uap, how), NULL, &kboset); if (SCARG(uap, oset) == NULL || error != 0) return error; native_sigset_to_sigset13(&kboset, &kdset); return copyout(&kdset, SCARG(uap, oset), sizeof(kdset)); }
void native_sigaction13_to_sigaction(const struct sigaction13 *osa, struct sigaction *sa) { sa->sa_handler = osa->osa_handler; native_sigset13_to_sigset(&osa->osa_mask, &sa->sa_mask); sa->sa_flags = osa->osa_flags; }
int compat_13_sys_sigsuspend(struct lwp *l, const struct compat_13_sys_sigsuspend_args *uap, register_t *retval) { /* { syscallarg(sigset13_t) mask; } */ sigset13_t ess; sigset_t bss; ess = SCARG(uap, mask); native_sigset13_to_sigset(&ess, &bss); return (sigsuspend1(l, &bss)); }
int ultrix_sys_sigvec(struct lwp *l, const struct ultrix_sys_sigvec_args *uap, register_t *retval) { struct sigvec nsv, osv; struct sigaction nsa, osa; int error; if (SCARG(uap, nsv)) { error = copyin(SCARG(uap, nsv), &nsv, sizeof(nsv)); if (error) return error; nsa.sa_handler = nsv.sv_handler; #if 0 /* documentation */ /* ONSTACK is identical */ nsa.sa_flags = nsv.sv_flags & ULTRIX_SV_ONSTACK; if ((nsv.sv_flags & ULTRIX_SV_OLDSIG) /* old signal() - always restart */ || (!(nsv.sv_flags & ULTRIX_SV_INTERRUPT)) /* inverted meaning (same bit) */ ) nsa.sa_flags |= SA_RESTART; #else /* optimized - assuming ULTRIX_SV_OLDSIG=>!ULTRIX_SV_INTERRUPT */ nsa.sa_flags = nsv.sv_flags & ~ULTRIX_SV_OLDSIG; nsa.sa_flags ^= SA_RESTART; #endif native_sigset13_to_sigset(&nsv.sv_mask, &nsa.sa_mask); } error = sigaction1(l, SCARG(uap, signum), SCARG(uap, nsv) ? &nsa : 0, SCARG(uap, osv) ? &osa : 0, NULL, 0); if (error) return error; if (SCARG(uap, osv)) { osv.sv_handler = osa.sa_handler; osv.sv_flags = osa.sa_flags ^ SA_RESTART; osv.sv_flags &= (ULTRIX_SV_ONSTACK | ULTRIX_SV_INTERRUPT); native_sigset_to_sigset13(&osa.sa_mask, &osv.sv_mask); error = copyout(&osv, SCARG(uap, osv), sizeof(osv)); if (error) return error; } return 0; }
int compat_13_netbsd32_sigprocmask(struct lwp *l, const struct compat_13_netbsd32_sigprocmask_args *uap, register_t *retval) { /* { syscallarg(int) how; syscallarg(int) mask; } */ sigset13_t ness, oess; sigset_t nbss, obss; int error; ness = SCARG(uap, mask); native_sigset13_to_sigset(&ness, &nbss); error = sigprocmask1(l, SCARG(uap, how), &nbss, &obss); if (error) return (error); native_sigset_to_sigset13(&obss, &oess); *retval = oess; return (0); }
int darwin_sys_sigaction(struct lwp *l, const struct darwin_sys_sigaction_args *uap, register_t *retval) { /* { syscallarg(int) signum; syscallarg(struct darwin___sigaction *) nsa; syscallarg(struct sigaction13 *) osa; } */ struct darwin___sigaction dsa; struct sigaction nsa, osa; struct sigaction13 sa13; int error; if ((error = copyin(SCARG(uap, nsa), &dsa, sizeof(dsa))) != 0) return error; nsa.sa_handler = dsa.darwin_sa_handler.__sa_handler; native_sigset13_to_sigset(&dsa.darwin_sa_mask, &nsa.sa_mask); if (dsa.darwin_sa_flags & ~DARWIN_SA_ALLBITS) { DPRINTF(("darwin_sys_sigaction: ignoring bits (flags = %x)\n", dsa.darwin_sa_flags)); } nsa.sa_flags = dsa.darwin_sa_flags & DARWIN_SA_ALLBITS; error = sigaction1(l, SCARG(uap, signum), &nsa, &osa, dsa.darwin_sa_tramp, 1); if (error != 0) return error; if (SCARG(uap, osa) == NULL) return 0; /* XXX: The returned structure has a different type to that supplied */ sa13.osa_handler = osa.sa_handler; sa13.osa_mask = osa.sa_mask.__bits[0]; native_sigset_to_sigset13(&osa.sa_mask, &sa13.osa_mask); sa13.osa_flags = osa.sa_flags; return copyout(&sa13, SCARG(uap, osa), sizeof(sa13)); }
int compat_13_sys_sigreturn(struct lwp *l, void *v, register_t *retval) { struct compat_13_sys_sigreturn_args /* { syscallarg(struct sigcontext13 *) sigcntxp; } */ *uap = v; struct proc *p = l->l_proc; struct trapframe *scf; struct sigcontext13 *ucntx; struct sigcontext13 ksc; sigset_t mask; scf = l->l_addr->u_pcb.framep; ucntx = SCARG(uap, sigcntxp); if (copyin((caddr_t)ucntx, (caddr_t)&ksc, sizeof(struct sigcontext))) return EINVAL; /* Compatibility mode? */ if ((ksc.sc_ps & (PSL_IPL | PSL_IS)) || ((ksc.sc_ps & (PSL_U | PSL_PREVU)) != (PSL_U | PSL_PREVU)) || (ksc.sc_ps & PSL_CM)) { return (EINVAL); } if (ksc.sc_onstack & SS_ONSTACK) p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; else p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK; native_sigset13_to_sigset(&ksc.sc_mask, &mask); (void) sigprocmask1(p, SIG_SETMASK, &mask, 0); scf->fp = ksc.sc_fp; scf->ap = ksc.sc_ap; scf->pc = ksc.sc_pc; scf->sp = ksc.sc_sp; scf->psl = ksc.sc_ps; return (EJUSTRETURN); }
int compat_13_sys_sigprocmask(struct lwp *l, const struct compat_13_sys_sigprocmask_args *uap, register_t *retval) { /* { syscallarg(int) how; syscallarg(int) mask; } */ struct proc *p = l->l_proc; sigset13_t ness, oess; sigset_t nbss, obss; int error; ness = SCARG(uap, mask); native_sigset13_to_sigset(&ness, &nbss); mutex_enter(p->p_lock); error = sigprocmask1(l, SCARG(uap, how), &nbss, &obss); mutex_exit(p->p_lock); if (error) return (error); native_sigset_to_sigset13(&obss, &oess); *retval = oess; return (0); }
int compat_13_sys_sigreturn(struct proc *p, void *v, register_t *retval) { struct compat_13_sys_sigreturn_args /* { syscallarg(struct sigcontext13 *) sigcntxp; } */ *uap = v; struct sigcontext13 *scp, context; struct trapframe *tf; sigset_t mask; /* * The trampoline code hands us the context. * It is unsafe to keep track of it ourselves, in the event that a * program jumps out of a signal handler. */ scp = SCARG(uap, sigcntxp); if (copyin((caddr_t)scp, &context, sizeof(*scp)) != 0) return (EFAULT); /* * Make sure the processor mode has not been tampered with and * interrupts have not been disabled. */ #ifdef __PROG32 if ((context.sc_spsr & PSR_MODE) != PSR_USR32_MODE || (context.sc_spsr & (I32_bit | F32_bit)) != 0) return (EINVAL); #else /* __PROG26 */ if ((context.sc_pc & R15_MODE) != R15_MODE_USR || (context.sc_pc & (R15_IRQ_DISABLE | R15_FIQ_DISABLE)) != 0) return EINVAL; #endif /* Restore register context. */ tf = p->p_addr->u_pcb.pcb_tf; tf->tf_r0 = context.sc_r0; tf->tf_r1 = context.sc_r1; tf->tf_r2 = context.sc_r2; tf->tf_r3 = context.sc_r3; tf->tf_r4 = context.sc_r4; tf->tf_r5 = context.sc_r5; tf->tf_r6 = context.sc_r6; tf->tf_r7 = context.sc_r7; tf->tf_r8 = context.sc_r8; tf->tf_r9 = context.sc_r9; tf->tf_r10 = context.sc_r10; tf->tf_r11 = context.sc_r11; tf->tf_r12 = context.sc_r12; tf->tf_usr_sp = context.sc_usr_sp; tf->tf_usr_lr = context.sc_usr_lr; tf->tf_svc_lr = context.sc_svc_lr; tf->tf_pc = context.sc_pc; tf->tf_spsr = context.sc_spsr; /* Restore signal stack. */ if (context.sc_onstack & SS_ONSTACK) p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK; else p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK; /* Restore signal mask. */ native_sigset13_to_sigset(&context.sc_mask, &mask); (void) sigprocmask1(p, SIG_SETMASK, &mask, 0); return (EJUSTRETURN); }
int compat_13_netbsd32_sigreturn(struct lwp *l, const struct compat_13_netbsd32_sigreturn_args *uap, register_t *retval) { /* { syscallarg(struct netbsd32_sigcontext13 *) sigcntxp; } */ struct netbsd32_sigcontext13 *scp; struct netbsd32_sigcontext13 sc; struct trapframe64 *tf; struct proc *p = l->l_proc; sigset_t mask; /* First ensure consistent stack state (see sendsig). */ write_user_windows(); if (rwindow_save(l)) { #ifdef DEBUG printf("compat_13_netbsd32_sigreturn: rwindow_save(%p) failed, sending SIGILL\n", p); Debugger(); #endif mutex_enter(p->p_lock); sigexit(l, SIGILL); } #ifdef DEBUG if (sigdebug & SDB_FOLLOW) { printf("compat_13_netbsd32_sigreturn: %s[%d], sigcntxp %p\n", p->p_comm, p->p_pid, SCARG(uap, sigcntxp)); if (sigdebug & SDB_DDB) Debugger(); } #endif scp = (struct netbsd32_sigcontext13 *)(u_long)SCARG(uap, sigcntxp); if ((vaddr_t)scp & 3 || (copyin((void *)scp, &sc, sizeof sc) != 0)) { #ifdef DEBUG printf("compat_13_netbsd32_sigreturn: copyin failed\n"); Debugger(); #endif return (EINVAL); } scp = ≻ tf = l->l_md.md_tf; /* * Only the icc bits in the psr are used, so it need not be * verified. pc and npc must be multiples of 4. This is all * that is required; if it holds, just do it. */ if (((sc.sc_pc | sc.sc_npc) & 3) != 0) #ifdef DEBUG { printf("compat_13_netbsd32_sigreturn: pc %p or npc %p invalid\n", sc.sc_pc, sc.sc_npc); Debugger(); return (EINVAL); } #else return (EINVAL); #endif /* take only psr ICC field */ tf->tf_tstate = (int64_t)(tf->tf_tstate & ~TSTATE_CCR) | PSRCC_TO_TSTATE(sc.sc_psr); tf->tf_pc = (int64_t)sc.sc_pc; tf->tf_npc = (int64_t)sc.sc_npc; tf->tf_global[1] = (int64_t)sc.sc_g1; tf->tf_out[0] = (int64_t)sc.sc_o0; tf->tf_out[6] = (int64_t)sc.sc_sp; #ifdef DEBUG if (sigdebug & SDB_FOLLOW) { printf("compat_13_netbsd32_sys_sigreturn: return trapframe pc=%p sp=%p tstate=%x\n", (int)tf->tf_pc, (int)tf->tf_out[6], (int)tf->tf_tstate); if (sigdebug & SDB_DDB) Debugger(); } #endif mutex_enter(p->p_lock); if (scp->sc_onstack & SS_ONSTACK) l->l_sigstk.ss_flags |= SS_ONSTACK; else l->l_sigstk.ss_flags &= ~SS_ONSTACK; /* Restore signal mask */ native_sigset13_to_sigset((sigset13_t *)&scp->sc_mask, &mask); (void) sigprocmask1(l, SIG_SETMASK, &mask, 0); mutex_exit(p->p_lock); return (EJUSTRETURN); }
int compat_13_sys_sigreturn(struct lwp *l, const struct compat_13_sys_sigreturn_args *uap, register_t *retval) { /* { syscallarg(struct sigcontext13 *) sigcntxp; } */ struct sigcontext13 *scp, context; struct trapframe * const tf = lwp_trapframe(l); struct proc * const p = l->l_proc; sigset_t mask; /* * The trampoline code hands us the context. * It is unsafe to keep track of it ourselves, in the event that a * program jumps out of a signal handler. */ scp = SCARG(uap, sigcntxp); if (copyin((void *)scp, &context, sizeof(*scp)) != 0) return (EFAULT); /* * Make sure the processor mode has not been tampered with and * interrupts have not been disabled. */ if (!VALID_R15_PSR(context.sc_pc, context.sc_spsr)) return EINVAL; /* Restore register context. */ tf->tf_r0 = context.sc_r0; tf->tf_r1 = context.sc_r1; tf->tf_r2 = context.sc_r2; tf->tf_r3 = context.sc_r3; tf->tf_r4 = context.sc_r4; tf->tf_r5 = context.sc_r5; tf->tf_r6 = context.sc_r6; tf->tf_r7 = context.sc_r7; tf->tf_r8 = context.sc_r8; tf->tf_r9 = context.sc_r9; tf->tf_r10 = context.sc_r10; tf->tf_r11 = context.sc_r11; tf->tf_r12 = context.sc_r12; tf->tf_usr_sp = context.sc_usr_sp; tf->tf_usr_lr = context.sc_usr_lr; tf->tf_svc_lr = context.sc_svc_lr; tf->tf_pc = context.sc_pc; tf->tf_spsr = context.sc_spsr; mutex_enter(p->p_lock); /* Restore signal stack. */ if (context.sc_onstack & SS_ONSTACK) l->l_sigstk.ss_flags |= SS_ONSTACK; else l->l_sigstk.ss_flags &= ~SS_ONSTACK; /* Restore signal mask. */ native_sigset13_to_sigset(&context.sc_mask, &mask); (void) sigprocmask1(l, SIG_SETMASK, &mask, 0); mutex_exit(p->p_lock); return (EJUSTRETURN); }
int compat_13_netbsd32_sigreturn(struct lwp *l, const struct compat_13_netbsd32_sigreturn_args *uap, register_t *retval) { /* { syscallarg(struct netbsd32_sigcontext13 *) sigcntxp; } */ struct proc *p = l->l_proc; struct netbsd32_sigcontext13 *scp, context; struct trapframe *tf; sigset_t mask; int error; /* * The trampoline code hands us the context. * It is unsafe to keep track of it ourselves, in the event that a * program jumps out of a signal handler. */ scp = (struct netbsd32_sigcontext13 *)NETBSD32PTR64(SCARG(uap, sigcntxp)); if (copyin((void *)scp, &context, sizeof(*scp)) != 0) return (EFAULT); /* Restore register context. */ tf = l->l_md.md_regs; /* * Check for security violations. */ error = check_sigcontext32(l, (const struct netbsd32_sigcontext *)&context); if (error != 0) return error; tf->tf_gs = context.sc_gs; tf->tf_fs = context.sc_fs; tf->tf_es = context.sc_es; tf->tf_ds = context.sc_ds; tf->tf_rflags = context.sc_eflags; tf->tf_rdi = context.sc_edi; tf->tf_rsi = context.sc_esi; tf->tf_rbp = context.sc_ebp; tf->tf_rbx = context.sc_ebx; tf->tf_rdx = context.sc_edx; tf->tf_rcx = context.sc_ecx; tf->tf_rax = context.sc_eax; tf->tf_rip = context.sc_eip; tf->tf_cs = context.sc_cs; tf->tf_rsp = context.sc_esp; tf->tf_ss = context.sc_ss; mutex_enter(p->p_lock); /* Restore signal stack. */ if (context.sc_onstack & SS_ONSTACK) l->l_sigstk.ss_flags |= SS_ONSTACK; else l->l_sigstk.ss_flags &= ~SS_ONSTACK; /* Restore signal mask. */ native_sigset13_to_sigset((sigset13_t *)&context.sc_mask, &mask); (void) sigprocmask1(l, SIG_SETMASK, &mask, 0); mutex_exit(p->p_lock); return (EJUSTRETURN); }
/* * System call to cleanup state after a signal * has been taken. Reset signal mask and * stack state from context left by sendsig (above). * Return to previous pc and psl as specified by * context left by sendsig. Check carefully to * make sure that the user has not modified the * psl to gain improper privileges or to cause * a machine fault. */ int compat_13_sys_sigreturn(struct lwp *l, const struct compat_13_sys_sigreturn_args *uap, register_t *retval) { /* { syscallarg(struct sigcontext13 *) sigcntxp; } */ struct proc *p = l->l_proc; struct sigcontext13 *scp; struct frame *frame; struct sigcontext13 tsigc; sigset_t mask; /* * The trampoline code hands us the context. * It is unsafe to keep track of it ourselves, in the event that a * program jumps out of a signal handler. */ scp = SCARG(uap, sigcntxp); if ((int)scp & 1) return EINVAL; if (copyin(scp, &tsigc, sizeof(tsigc)) != 0) return EFAULT; scp = &tsigc; /* Make sure the user isn't pulling a fast one on us! */ if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0) return EINVAL; /* Restore register context. */ frame = (struct frame *)l->l_md.md_regs; /* * We only support restoring the sigcontext13 in this call. * We are not called from the sigcode (per sendsig()), so * we will not have a sigstate to restore. */ if (scp->sc_ap != 0) return EINVAL; /* * Restore the user supplied information. * This should be at the last so that the error (EINVAL) * is reported to the sigreturn caller, not to the * jump destination. */ frame->f_regs[SP] = scp->sc_sp; frame->f_regs[A6] = scp->sc_fp; frame->f_pc = scp->sc_pc; frame->f_sr = scp->sc_ps; mutex_enter(p->p_lock); /* Restore signal stack. */ if (scp->sc_onstack & SS_ONSTACK) l->l_sigstk.ss_flags |= SS_ONSTACK; else l->l_sigstk.ss_flags &= ~SS_ONSTACK; /* Restore signal mask. */ native_sigset13_to_sigset(&scp->sc_mask, &mask); (void)sigprocmask1(l, SIG_SETMASK, &mask, 0); mutex_exit(p->p_lock); return EJUSTRETURN; }
int compat_13_sys_sigreturn(struct lwp *l, const struct compat_13_sys_sigreturn_args *uap, register_t *retval) { /* { syscallarg(struct sigcontext13 *) sigcntxp; } */ struct proc *p = l->l_proc; struct sigcontext13 *scp, context; struct trapframe *tf; sigset_t mask; /* * The trampoline code hands us the context. * It is unsafe to keep track of it ourselves, in the event that a * program jumps out of a signal handler. */ scp = SCARG(uap, sigcntxp); if (copyin((void *)scp, &context, sizeof(*scp)) != 0) return (EFAULT); /* Restore register context. */ tf = l->l_md.md_regs; #ifdef VM86 if (context.sc_eflags & PSL_VM) { void syscall_vm86(struct trapframe *); tf->tf_vm86_gs = context.sc_gs; tf->tf_vm86_fs = context.sc_fs; tf->tf_vm86_es = context.sc_es; tf->tf_vm86_ds = context.sc_ds; set_vflags(l, context.sc_eflags); p->p_md.md_syscall = syscall_vm86; } else #endif { /* * Check for security violations. If we're returning to * protected mode, the CPU will validate the segment registers * automatically and generate a trap on violations. We handle * the trap, rather than doing all of the checking here. */ if (((context.sc_eflags ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 || !USERMODE(context.sc_cs, context.sc_eflags)) return (EINVAL); tf->tf_gs = context.sc_gs; tf->tf_fs = context.sc_fs; tf->tf_es = context.sc_es; tf->tf_ds = context.sc_ds; tf->tf_eflags &= ~PSL_USER; tf->tf_eflags |= context.sc_eflags & PSL_USER; } tf->tf_edi = context.sc_edi; tf->tf_esi = context.sc_esi; tf->tf_ebp = context.sc_ebp; tf->tf_ebx = context.sc_ebx; tf->tf_edx = context.sc_edx; tf->tf_ecx = context.sc_ecx; tf->tf_eax = context.sc_eax; tf->tf_eip = context.sc_eip; tf->tf_cs = context.sc_cs; tf->tf_esp = context.sc_esp; tf->tf_ss = context.sc_ss; mutex_enter(p->p_lock); /* Restore signal stack. */ if (context.sc_onstack & SS_ONSTACK) l->l_sigstk.ss_flags |= SS_ONSTACK; else l->l_sigstk.ss_flags &= ~SS_ONSTACK; /* Restore signal mask. */ native_sigset13_to_sigset(&context.sc_mask, &mask); (void) sigprocmask1(l, SIG_SETMASK, &mask, 0); mutex_exit(p->p_lock); return (EJUSTRETURN); }