diff options
author | kib <kib@FreeBSD.org> | 2009-10-27 10:47:58 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2009-10-27 10:47:58 +0000 |
commit | ce081b037e7a762f0dd090a207cafc5121f39f51 (patch) | |
tree | 359a5b0885ae5a789f55ba40dc485621e67c34b1 /sys/compat | |
parent | eb4c68098b66d84de3abc7be00acfdc6d2f8f980 (diff) | |
download | FreeBSD-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.c | 23 |
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); } |