summaryrefslogtreecommitdiffstats
path: root/lib/libpthread/thread/thr_sigsuspend.c
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2003-07-07 04:28:23 +0000
committerdavidxu <davidxu@FreeBSD.org>2003-07-07 04:28:23 +0000
commit8aa4e2d6856d1eed699b30ccca6163f8e501e183 (patch)
tree6539674ba4c0ff3018faf64006ac81eb9090ec5f /lib/libpthread/thread/thr_sigsuspend.c
parente95dd66c1f7fd662d47b34b5d83f1dcaa8b150e3 (diff)
downloadFreeBSD-src-8aa4e2d6856d1eed699b30ccca6163f8e501e183.zip
FreeBSD-src-8aa4e2d6856d1eed699b30ccca6163f8e501e183.tar.gz
Avoid accessing user provided parameters in critical region.
Reviewed by: deischen
Diffstat (limited to 'lib/libpthread/thread/thr_sigsuspend.c')
-rw-r--r--lib/libpthread/thread/thr_sigsuspend.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/lib/libpthread/thread/thr_sigsuspend.c b/lib/libpthread/thread/thr_sigsuspend.c
index 8d087f5..869e3d9 100644
--- a/lib/libpthread/thread/thr_sigsuspend.c
+++ b/lib/libpthread/thread/thr_sigsuspend.c
@@ -43,20 +43,23 @@ int
_sigsuspend(const sigset_t *set)
{
struct pthread *curthread = _get_curthread();
+ sigset_t oldmask, newmask;
int ret = -1;
- sigset_t osigmask;
if (!_kse_isthreaded())
return __sys_sigsuspend(set);
/* Check if a new signal set was provided by the caller: */
if (set != NULL) {
+ newmask = *set;
+
THR_LOCK_SWITCH(curthread);
/* Save current sigmask */
- memcpy(&osigmask, &curthread->sigmask, sizeof(osigmask));
+ memcpy(&oldmask, &curthread->sigmask, sizeof(sigset_t));
+
/* Change the caller's mask: */
- memcpy(&curthread->sigmask, set, sizeof(sigset_t));
+ memcpy(&curthread->sigmask, &newmask, sizeof(sigset_t));
THR_SET_STATE(curthread, PS_SIGSUSPEND);
@@ -68,7 +71,7 @@ _sigsuspend(const sigset_t *set)
THR_SCHED_LOCK(curthread, curthread);
/* Restore the signal mask: */
- memcpy(&curthread->sigmask, &osigmask, sizeof(sigset_t));
+ memcpy(&curthread->sigmask, &oldmask, sizeof(sigset_t));
THR_SCHED_UNLOCK(curthread, curthread);
/*
* signal mask is reloaded, need to check if there is
OpenPOWER on IntegriCloud