diff options
author | raf <none@none> | 2008-01-14 18:02:51 -0800 |
---|---|---|
committer | raf <none@none> | 2008-01-14 18:02:51 -0800 |
commit | 9ac35488880927260db6ad8111329c1f70dd4627 (patch) | |
tree | 325e15a275d4b6cb3fd48e006524481cd7f58d54 | |
parent | bc37da3aa8455efcf567c456746e3fb9d7f0a189 (diff) | |
download | illumos-gate-9ac35488880927260db6ad8111329c1f70dd4627.tar.gz |
6650138 Fix for 6598201 causes user-level sleep queue data corruption
-rw-r--r-- | usr/src/lib/libc/port/threads/sigaction.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/usr/src/lib/libc/port/threads/sigaction.c b/usr/src/lib/libc/port/threads/sigaction.c index 5419756719..8e52b04a8c 100644 --- a/usr/src/lib/libc/port/threads/sigaction.c +++ b/usr/src/lib/libc/port/threads/sigaction.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -236,8 +236,20 @@ take_deferred_signal(int sig) * the kernel has reset the handler to SIG_DFL, so we have * to reestablish the handler now so that it will be entered * again when we call __sigresend(), below. + * + * Logically, we should acquire and release the signal's + * sig_lock around this operation to protect the integrity + * of the signal action while we copy it, as is done below + * in _libc_sigaction(). However, we may be on a user-level + * sleep queue at this point and lrw_wrlock(&suap->sig_lock) + * might attempt to sleep on a different sleep queue and + * that would corrupt the entire sleep queue mechanism. + * + * If we are on a sleep queue we will remove ourself from + * it in call_user_handler(), called from sigacthandler(), + * before entering the application's signal handler. + * In the meantime, we must not acquire any locks. */ - lrw_wrlock(&suap->sig_lock); if (suap->sig_uaction.sa_flags & SA_RESETHAND) { struct sigaction tact = suap->sig_uaction; tact.sa_flags &= ~SA_NODEFER; @@ -245,7 +257,6 @@ take_deferred_signal(int sig) tact.sa_mask = maskset; (void) __sigaction(sig, &tact, NULL); } - lrw_unlock(&suap->sig_lock); if (self->ul_siginfo.si_signo == 0) sip = NULL; |