diff options
author | marcel <marcel@FreeBSD.org> | 2000-11-30 05:23:49 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2000-11-30 05:23:49 +0000 |
commit | 75c76bdc6b73745ecfa9955e547ca6ba4fd7d328 (patch) | |
tree | c43af70e24691529e40621dabcaf4913d9d353f4 /sys/pc98 | |
parent | 673e30eadab9fe762d23631609edf13e018f59c1 (diff) | |
download | FreeBSD-src-75c76bdc6b73745ecfa9955e547ca6ba4fd7d328.zip FreeBSD-src-75c76bdc6b73745ecfa9955e547ca6ba4fd7d328.tar.gz |
Don't use p->p_sigstk.ss_flags to keep state of whether the
process is on the alternate stack or not. For compatibility
with sigstack(2) state is being updated if such is needed.
We now determine whether the process is on the alternate
stack by looking at its stack pointer. This allows a process
to siglongjmp from a signal handler on the alternate stack
to the place of the sigsetjmp on the normal stack. When
maintaining state, this would have invalidated the state
information and causing a subsequent signal to be delivered
on the normal stack instead of the alternate stack.
PR: 22286
Diffstat (limited to 'sys/pc98')
-rw-r--r-- | sys/pc98/i386/machdep.c | 22 | ||||
-rw-r--r-- | sys/pc98/pc98/machdep.c | 22 |
2 files changed, 34 insertions, 10 deletions
diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c index 0320ad0..a756749 100644 --- a/sys/pc98/i386/machdep.c +++ b/sys/pc98/i386/machdep.c @@ -495,14 +495,16 @@ osendsig(catcher, sig, mask, code) p = curproc; psp = p->p_sigacts; regs = p->p_md.md_regs; - oonstack = p->p_sigstk.ss_flags & SS_ONSTACK; + oonstack = sigonstack(regs->tf_esp); /* Allocate and validate space for the signal handler context. */ if ((p->p_flag & P_ALTSTACK) && !oonstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { fp = (struct osigframe *)(p->p_sigstk.ss_sp + p->p_sigstk.ss_size - sizeof(struct osigframe)); +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) p->p_sigstk.ss_flags |= SS_ONSTACK; +#endif } else fp = (struct osigframe *)regs->tf_esp - 1; @@ -561,7 +563,7 @@ osendsig(catcher, sig, mask, code) sf.sf_siginfo.si_sc.sc_isp = regs->tf_isp; /* Build the signal context to be used by osigreturn(). */ - sf.sf_siginfo.si_sc.sc_onstack = oonstack; + sf.sf_siginfo.si_sc.sc_onstack = (oonstack) ? 1 : 0; SIG2OSIG(*mask, sf.sf_siginfo.si_sc.sc_mask); sf.sf_siginfo.si_sc.sc_sp = regs->tf_esp; sf.sf_siginfo.si_sc.sc_fp = regs->tf_ebp; @@ -634,13 +636,15 @@ sendsig(catcher, sig, mask, code) return; } regs = p->p_md.md_regs; - oonstack = p->p_sigstk.ss_flags & SS_ONSTACK; + oonstack = sigonstack(regs->tf_esp); /* Save user context. */ bzero(&sf, sizeof(sf)); sf.sf_uc.uc_sigmask = *mask; sf.sf_uc.uc_stack = p->p_sigstk; - sf.sf_uc.uc_mcontext.mc_onstack = oonstack; + sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK) + ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; + sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; sf.sf_uc.uc_mcontext.mc_gs = rgs(); bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs)); @@ -649,7 +653,9 @@ sendsig(catcher, sig, mask, code) SIGISMEMBER(psp->ps_sigonstack, sig)) { sfp = (struct sigframe *)(p->p_sigstk.ss_sp + p->p_sigstk.ss_size - sizeof(struct sigframe)); +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) p->p_sigstk.ss_flags |= SS_ONSTACK; +#endif } else sfp = (struct sigframe *)regs->tf_esp - 1; @@ -850,10 +856,13 @@ osigreturn(p, uap) regs->tf_ss = scp->sc_ss; regs->tf_isp = scp->sc_isp; - if (scp->sc_onstack & 01) +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) + if (scp->sc_onstack & 1) p->p_sigstk.ss_flags |= SS_ONSTACK; else p->p_sigstk.ss_flags &= ~SS_ONSTACK; +#endif + SIGSETOLD(p->p_sigmask, scp->sc_mask); SIG_CANTMASK(p->p_sigmask); regs->tf_ebp = scp->sc_fp; @@ -959,10 +968,13 @@ sigreturn(p, uap) bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs)); } + +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) if (ucp->uc_mcontext.mc_onstack & 1) p->p_sigstk.ss_flags |= SS_ONSTACK; else p->p_sigstk.ss_flags &= ~SS_ONSTACK; +#endif p->p_sigmask = ucp->uc_sigmask; SIG_CANTMASK(p->p_sigmask); diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c index 0320ad0..a756749 100644 --- a/sys/pc98/pc98/machdep.c +++ b/sys/pc98/pc98/machdep.c @@ -495,14 +495,16 @@ osendsig(catcher, sig, mask, code) p = curproc; psp = p->p_sigacts; regs = p->p_md.md_regs; - oonstack = p->p_sigstk.ss_flags & SS_ONSTACK; + oonstack = sigonstack(regs->tf_esp); /* Allocate and validate space for the signal handler context. */ if ((p->p_flag & P_ALTSTACK) && !oonstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { fp = (struct osigframe *)(p->p_sigstk.ss_sp + p->p_sigstk.ss_size - sizeof(struct osigframe)); +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) p->p_sigstk.ss_flags |= SS_ONSTACK; +#endif } else fp = (struct osigframe *)regs->tf_esp - 1; @@ -561,7 +563,7 @@ osendsig(catcher, sig, mask, code) sf.sf_siginfo.si_sc.sc_isp = regs->tf_isp; /* Build the signal context to be used by osigreturn(). */ - sf.sf_siginfo.si_sc.sc_onstack = oonstack; + sf.sf_siginfo.si_sc.sc_onstack = (oonstack) ? 1 : 0; SIG2OSIG(*mask, sf.sf_siginfo.si_sc.sc_mask); sf.sf_siginfo.si_sc.sc_sp = regs->tf_esp; sf.sf_siginfo.si_sc.sc_fp = regs->tf_ebp; @@ -634,13 +636,15 @@ sendsig(catcher, sig, mask, code) return; } regs = p->p_md.md_regs; - oonstack = p->p_sigstk.ss_flags & SS_ONSTACK; + oonstack = sigonstack(regs->tf_esp); /* Save user context. */ bzero(&sf, sizeof(sf)); sf.sf_uc.uc_sigmask = *mask; sf.sf_uc.uc_stack = p->p_sigstk; - sf.sf_uc.uc_mcontext.mc_onstack = oonstack; + sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK) + ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; + sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; sf.sf_uc.uc_mcontext.mc_gs = rgs(); bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs)); @@ -649,7 +653,9 @@ sendsig(catcher, sig, mask, code) SIGISMEMBER(psp->ps_sigonstack, sig)) { sfp = (struct sigframe *)(p->p_sigstk.ss_sp + p->p_sigstk.ss_size - sizeof(struct sigframe)); +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) p->p_sigstk.ss_flags |= SS_ONSTACK; +#endif } else sfp = (struct sigframe *)regs->tf_esp - 1; @@ -850,10 +856,13 @@ osigreturn(p, uap) regs->tf_ss = scp->sc_ss; regs->tf_isp = scp->sc_isp; - if (scp->sc_onstack & 01) +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) + if (scp->sc_onstack & 1) p->p_sigstk.ss_flags |= SS_ONSTACK; else p->p_sigstk.ss_flags &= ~SS_ONSTACK; +#endif + SIGSETOLD(p->p_sigmask, scp->sc_mask); SIG_CANTMASK(p->p_sigmask); regs->tf_ebp = scp->sc_fp; @@ -959,10 +968,13 @@ sigreturn(p, uap) bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs)); } + +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) if (ucp->uc_mcontext.mc_onstack & 1) p->p_sigstk.ss_flags |= SS_ONSTACK; else p->p_sigstk.ss_flags &= ~SS_ONSTACK; +#endif p->p_sigmask = ucp->uc_sigmask; SIG_CANTMASK(p->p_sigmask); |