Print this page
5281 incorrect realtime signal delivery


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*

  23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #include "lint.h"
  28 #include <sys/feature_tests.h>
  29 /*
  30  * setcontext() really can return, if UC_CPU is not specified.
  31  * Make the compiler shut up about it.
  32  */
  33 #if defined(__NORETURN)
  34 #undef  __NORETURN
  35 #endif
  36 #define __NORETURN
  37 #include "thr_uberdata.h"
  38 #include "asyncio.h"
  39 #include <signal.h>
  40 #include <siginfo.h>
  41 #include <sys/systm.h>
  42 


  53          * We only test valid signal bits, not rubbish following MAXSIG
  54          * (for speed).  Algorithm:
  55          * if (s1 & fillset) == (s2 & fillset) then (s1 ^ s2) & fillset == 0
  56          */
  57 /* see lib/libc/inc/thr_uberdata.h for why this must be true */
  58 #if (MAXSIG > (2 * 32) && MAXSIG <= (3 * 32))
  59         return (!((s1->__sigbits[0] ^ s2->__sigbits[0]) |
  60             (s1->__sigbits[1] ^ s2->__sigbits[1]) |
  61             ((s1->__sigbits[2] ^ s2->__sigbits[2]) & FILLSET2)));
  62 #else
  63 #error "fix me: MAXSIG out of bounds"
  64 #endif
  65 }
  66 
  67 /*
  68  * Common code for calling the user-specified signal handler.
  69  */
  70 void
  71 call_user_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
  72 {

  73         ulwp_t *self = curthread;
  74         uberdata_t *udp = self->ul_uberdata;
  75         struct sigaction uact;
  76         volatile struct sigaction *sap;
  77 
  78         /*
  79          * If we are taking a signal while parked or about to be parked
  80          * on __lwp_park() then remove ourself from the sleep queue so
  81          * that we can grab locks.  The code in mutex_lock_queue() and
  82          * cond_wait_common() will detect this and deal with it when
  83          * __lwp_park() returns.
  84          */
  85         unsleep_self();
  86         set_parking_flag(self, 0);
  87 
  88         if (__td_event_report(self, TD_CATCHSIG, udp)) {
  89                 self->ul_td_evbuf.eventnum = TD_CATCHSIG;
  90                 self->ul_td_evbuf.eventdata = (void *)(intptr_t)sig;
  91                 tdb_event(TD_CATCHSIG, udp);
  92         }


 138          * signal mask for sigsuspend() or pollsys() (self->ul_tmpmask) but
 139          * /proc can override this via PCSSIG, so we don't bother.
 140          *
 141          * We would also like to ASSERT() that the signal mask at the previous
 142          * level equals self->ul_sigmask (maskset for sigsuspend() / pollsys()),
 143          * but /proc can change the thread's signal mask via PCSHOLD, so we
 144          * don't bother with that either.
 145          */
 146         ASSERT(ucp->uc_flags & UC_SIGMASK);
 147         if (self->ul_sigsuspend) {
 148                 ucp->uc_sigmask = self->ul_sigmask;
 149                 self->ul_sigsuspend = 0;
 150                 /* the sigsuspend() or pollsys() signal mask */
 151                 sigorset(&uact.sa_mask, &self->ul_tmpmask);
 152         } else {
 153                 /* the signal mask at the previous level */
 154                 sigorset(&uact.sa_mask, &ucp->uc_sigmask);
 155         }
 156         if (!(uact.sa_flags & SA_NODEFER))  /* add current signal */
 157                 (void) sigaddset(&uact.sa_mask, sig);














 158         self->ul_sigmask = uact.sa_mask;
 159         self->ul_siglink = ucp;
 160         (void) __lwp_sigmask(SIG_SETMASK, &uact.sa_mask);
 161 
 162         /*
 163          * If this thread has been sent SIGCANCEL from the kernel
 164          * or from pthread_cancel(), it is being asked to exit.
 165          * The kernel may send SIGCANCEL without a siginfo struct.
 166          * If the SIGCANCEL is process-directed (from kill() or
 167          * sigqueue()), treat it as an ordinary signal.
 168          */
 169         if (sig == SIGCANCEL) {
 170                 if (sip == NULL || SI_FROMKERNEL(sip) ||
 171                     sip->si_code == SI_LWP) {
 172                         do_sigcancel();
 173                         goto out;
 174                 }
 175                 /* SIGCANCEL is ignored by default */
 176                 if (uact.sa_sigaction == SIG_DFL ||
 177                     uact.sa_sigaction == SIG_IGN)




   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2014 Ryan Zezeski.  All rights reserved.
  24  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  25  * Use is subject to license terms.
  26  */
  27 
  28 #include "lint.h"
  29 #include <sys/feature_tests.h>
  30 /*
  31  * setcontext() really can return, if UC_CPU is not specified.
  32  * Make the compiler shut up about it.
  33  */
  34 #if defined(__NORETURN)
  35 #undef  __NORETURN
  36 #endif
  37 #define __NORETURN
  38 #include "thr_uberdata.h"
  39 #include "asyncio.h"
  40 #include <signal.h>
  41 #include <siginfo.h>
  42 #include <sys/systm.h>
  43 


  54          * We only test valid signal bits, not rubbish following MAXSIG
  55          * (for speed).  Algorithm:
  56          * if (s1 & fillset) == (s2 & fillset) then (s1 ^ s2) & fillset == 0
  57          */
  58 /* see lib/libc/inc/thr_uberdata.h for why this must be true */
  59 #if (MAXSIG > (2 * 32) && MAXSIG <= (3 * 32))
  60         return (!((s1->__sigbits[0] ^ s2->__sigbits[0]) |
  61             (s1->__sigbits[1] ^ s2->__sigbits[1]) |
  62             ((s1->__sigbits[2] ^ s2->__sigbits[2]) & FILLSET2)));
  63 #else
  64 #error "fix me: MAXSIG out of bounds"
  65 #endif
  66 }
  67 
  68 /*
  69  * Common code for calling the user-specified signal handler.
  70  */
  71 void
  72 call_user_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
  73 {
  74         int i;
  75         ulwp_t *self = curthread;
  76         uberdata_t *udp = self->ul_uberdata;
  77         struct sigaction uact;
  78         volatile struct sigaction *sap;
  79 
  80         /*
  81          * If we are taking a signal while parked or about to be parked
  82          * on __lwp_park() then remove ourself from the sleep queue so
  83          * that we can grab locks.  The code in mutex_lock_queue() and
  84          * cond_wait_common() will detect this and deal with it when
  85          * __lwp_park() returns.
  86          */
  87         unsleep_self();
  88         set_parking_flag(self, 0);
  89 
  90         if (__td_event_report(self, TD_CATCHSIG, udp)) {
  91                 self->ul_td_evbuf.eventnum = TD_CATCHSIG;
  92                 self->ul_td_evbuf.eventdata = (void *)(intptr_t)sig;
  93                 tdb_event(TD_CATCHSIG, udp);
  94         }


 140          * signal mask for sigsuspend() or pollsys() (self->ul_tmpmask) but
 141          * /proc can override this via PCSSIG, so we don't bother.
 142          *
 143          * We would also like to ASSERT() that the signal mask at the previous
 144          * level equals self->ul_sigmask (maskset for sigsuspend() / pollsys()),
 145          * but /proc can change the thread's signal mask via PCSHOLD, so we
 146          * don't bother with that either.
 147          */
 148         ASSERT(ucp->uc_flags & UC_SIGMASK);
 149         if (self->ul_sigsuspend) {
 150                 ucp->uc_sigmask = self->ul_sigmask;
 151                 self->ul_sigsuspend = 0;
 152                 /* the sigsuspend() or pollsys() signal mask */
 153                 sigorset(&uact.sa_mask, &self->ul_tmpmask);
 154         } else {
 155                 /* the signal mask at the previous level */
 156                 sigorset(&uact.sa_mask, &ucp->uc_sigmask);
 157         }
 158         if (!(uact.sa_flags & SA_NODEFER))  /* add current signal */
 159                 (void) sigaddset(&uact.sa_mask, sig);
 160 
 161         /*
 162          * Enforce the proper order for realtime signals.  Lower signals
 163          * have higher priority and multiple instances of the same signal
 164          * must arrive in FIFO order (NODEFER does not apply).
 165          *
 166          * See section 2.4.2 of POSIX.
 167          */
 168         if ((sig >= SIGRTMIN) && (sig <= SIGRTMAX)) {
 169                 for (i = sig; i <= SIGRTMAX; i++) {
 170                         (void) sigaddset(&uact.sa_mask, i);
 171                 }
 172         }
 173 
 174         self->ul_sigmask = uact.sa_mask;
 175         self->ul_siglink = ucp;
 176         (void) __lwp_sigmask(SIG_SETMASK, &uact.sa_mask);
 177 
 178         /*
 179          * If this thread has been sent SIGCANCEL from the kernel
 180          * or from pthread_cancel(), it is being asked to exit.
 181          * The kernel may send SIGCANCEL without a siginfo struct.
 182          * If the SIGCANCEL is process-directed (from kill() or
 183          * sigqueue()), treat it as an ordinary signal.
 184          */
 185         if (sig == SIGCANCEL) {
 186                 if (sip == NULL || SI_FROMKERNEL(sip) ||
 187                     sip->si_code == SI_LWP) {
 188                         do_sigcancel();
 189                         goto out;
 190                 }
 191                 /* SIGCANCEL is ignored by default */
 192                 if (uact.sa_sigaction == SIG_DFL ||
 193                     uact.sa_sigaction == SIG_IGN)