summaryrefslogtreecommitdiffstats
path: root/sys/compat
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/compat
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/compat')
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c23
1 files changed, 7 insertions, 16 deletions
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 9f6b16d..37fa079 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -2482,7 +2482,7 @@ ofreebsd32_sigprocmask(struct thread *td,
int error;
OSIG2SIG(uap->mask, set);
- error = kern_sigprocmask(td, uap->how, &set, &oset, 1);
+ error = kern_sigprocmask(td, uap->how, &set, &oset, SIGPROCMASK_OLD);
SIG2OSIG(oset, td->td_retval[0]);
return (error);
}
@@ -2546,15 +2546,11 @@ int
ofreebsd32_sigblock(struct thread *td,
struct ofreebsd32_sigblock_args *uap)
{
- struct proc *p = td->td_proc;
- sigset_t set;
+ sigset_t set, oset;
OSIG2SIG(uap->mask, set);
- SIG_CANTMASK(set);
- PROC_LOCK(p);
- SIG2OSIG(td->td_sigmask, td->td_retval[0]);
- SIGSETOR(td->td_sigmask, set);
- PROC_UNLOCK(p);
+ kern_sigprocmask(td, SIG_BLOCK, &set, &oset, 0);
+ SIG2OSIG(oset, td->td_retval[0]);
return (0);
}
@@ -2562,16 +2558,11 @@ int
ofreebsd32_sigsetmask(struct thread *td,
struct ofreebsd32_sigsetmask_args *uap)
{
- struct proc *p = td->td_proc;
- sigset_t set;
+ sigset_t set, oset;
OSIG2SIG(uap->mask, set);
- SIG_CANTMASK(set);
- PROC_LOCK(p);
- SIG2OSIG(td->td_sigmask, td->td_retval[0]);
- SIGSETLO(td->td_sigmask, set);
- signotify(td);
- PROC_UNLOCK(p);
+ kern_sigprocmask(td, SIG_SETMASK, &set, &oset, 0);
+ SIG2OSIG(oset, td->td_retval[0]);
return (0);
}
OpenPOWER on IntegriCloud