summaryrefslogtreecommitdiffstats
path: root/sys/amd64/ia32
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2009-10-27 10:47:58 +0000
committerkib <kib@FreeBSD.org>2009-10-27 10:47:58 +0000
commitce081b037e7a762f0dd090a207cafc5121f39f51 (patch)
tree359a5b0885ae5a789f55ba40dc485621e67c34b1 /sys/amd64/ia32
parenteb4c68098b66d84de3abc7be00acfdc6d2f8f980 (diff)
downloadFreeBSD-src-ce081b037e7a762f0dd090a207cafc5121f39f51.zip
FreeBSD-src-ce081b037e7a762f0dd090a207cafc5121f39f51.tar.gz
In r197963, a race with thread being selected for signal delivery
while in kernel mode, and later changing signal mask to block the signal, was fixed for sigprocmask(2) and ptread_exit(3). The same race exists for sigreturn(2), setcontext(2) and swapcontext(2) syscalls. Use kern_sigprocmask() instead of direct manipulation of td_sigmask to reschedule newly blocked signals, closing the race. Reviewed by: davidxu Tested by: pho MFC after: 1 month
Diffstat (limited to 'sys/amd64/ia32')
-rw-r--r--sys/amd64/ia32/ia32_signal.c30
1 files changed, 8 insertions, 22 deletions
diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c
index d7c1dd5..10ec641 100644
--- a/sys/amd64/ia32/ia32_signal.c
+++ b/sys/amd64/ia32/ia32_signal.c
@@ -244,10 +244,8 @@ freebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap)
if (ret == 0) {
ret = ia32_set_mcontext(td, &uc.uc_mcontext);
if (ret == 0) {
- SIG_CANTMASK(uc.uc_sigmask);
- PROC_LOCK(td->td_proc);
- td->td_sigmask = uc.uc_sigmask;
- PROC_UNLOCK(td->td_proc);
+ kern_sigprocmask(td, SIG_SETMASK,
+ &uc.uc_sigmask, NULL, 0);
}
}
}
@@ -273,10 +271,8 @@ freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap)
if (ret == 0) {
ret = ia32_set_mcontext(td, &uc.uc_mcontext);
if (ret == 0) {
- SIG_CANTMASK(uc.uc_sigmask);
- PROC_LOCK(td->td_proc);
- td->td_sigmask = uc.uc_sigmask;
- PROC_UNLOCK(td->td_proc);
+ kern_sigprocmask(td, SIG_SETMASK,
+ &uc.uc_sigmask, NULL, 0);
}
}
}
@@ -544,9 +540,8 @@ freebsd4_freebsd32_sigreturn(td, uap)
} */ *uap;
{
struct ia32_ucontext4 uc;
- struct proc *p = td->td_proc;
struct trapframe *regs;
- const struct ia32_ucontext4 *ucp;
+ struct ia32_ucontext4 *ucp;
int cs, eflags, error;
ksiginfo_t ksi;
@@ -610,11 +605,7 @@ freebsd4_freebsd32_sigreturn(td, uap)
regs->tf_fs = ucp->uc_mcontext.mc_fs;
regs->tf_gs = ucp->uc_mcontext.mc_gs;
- PROC_LOCK(p);
- td->td_sigmask = ucp->uc_sigmask;
- SIG_CANTMASK(td->td_sigmask);
- signotify(td);
- PROC_UNLOCK(p);
+ kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
td->td_pcb->pcb_full_iret = 1;
return (EJUSTRETURN);
}
@@ -631,9 +622,8 @@ freebsd32_sigreturn(td, uap)
} */ *uap;
{
struct ia32_ucontext uc;
- struct proc *p = td->td_proc;
struct trapframe *regs;
- const struct ia32_ucontext *ucp;
+ struct ia32_ucontext *ucp;
int cs, eflags, error, ret;
ksiginfo_t ksi;
@@ -702,11 +692,7 @@ freebsd32_sigreturn(td, uap)
regs->tf_gs = ucp->uc_mcontext.mc_gs;
regs->tf_flags = TF_HASSEGS;
- PROC_LOCK(p);
- td->td_sigmask = ucp->uc_sigmask;
- SIG_CANTMASK(td->td_sigmask);
- signotify(td);
- PROC_UNLOCK(p);
+ kern_sigprocmask(td, SIG_SETMASK, &ucp->uc_sigmask, NULL, 0);
td->td_pcb->pcb_full_iret = 1;
return (EJUSTRETURN);
}
OpenPOWER on IntegriCloud