Home | History | Annotate | Download | only in coregrind
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Signal-related libc stuff.                    m_libcsignal.c ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2000-2017 Julian Seward
     11       jseward (at) acm.org
     12 
     13    This program is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License as
     15    published by the Free Software Foundation; either version 2 of the
     16    License, or (at your option) any later version.
     17 
     18    This program is distributed in the hope that it will be useful, but
     19    WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21    General Public License for more details.
     22 
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     26    02111-1307, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 */
     30 
     31 #include "pub_core_basics.h"
     32 #include "pub_core_debuglog.h"
     33 #include "pub_core_vki.h"
     34 #include "pub_core_vkiscnums.h"
     35 #include "pub_core_libcbase.h"
     36 #include "pub_core_libcassert.h"
     37 #include "pub_core_syscall.h"
     38 #include "pub_core_libcsignal.h"    /* self */
     39 
     40 #if !defined(VGO_solaris)
     41 #   define _VKI_MAXSIG (_VKI_NSIG - 1)
     42 #endif
     43 STATIC_ASSERT((_VKI_MAXSIG % _VKI_NSIG_BPW) != 0);
     44 
     45 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions
     46    of syscalls rather than the vanilla version, if a _nocancel version
     47    is available.  See docs/internals/Darwin-notes.txt for the reason
     48    why. */
     49 
     50 /* sigemptyset, sigfullset, sigaddset and sigdelset return 0 on
     51    success and -1 on error.  */
     52 /* In the sigset routines below, be aware that _VKI_NSIG_BPW can be
     53    either 32 or 64, and hence the sig[] words can either be 32- or
     54    64-bits.  And which they are it doesn't necessarily follow from the
     55    host word size. */
     56 
     57 /* Functions VG_(isemptysigset) and VG_(isfullsigset) check only bits that
     58    represent valid signals (i.e. signals <= _VKI_MAXSIG).  The same applies
     59    for the comparison in VG_(iseqsigset).  This is important because when
     60    a signal set is received from an operating system then bits which represent
     61    signals > _VKI_MAXSIG can have unexpected values for Valgrind. This is
     62    mainly specific to the Solaris kernel which clears these bits. */
     63 
     64 Int VG_(sigfillset)( vki_sigset_t* set )
     65 {
     66    Int i;
     67    if (set == NULL)
     68       return -1;
     69    for (i = 0; i < _VKI_NSIG_WORDS; i++)
     70       set->sig[i] = ~0;
     71    return 0;
     72 }
     73 
     74 Int VG_(sigemptyset)( vki_sigset_t* set )
     75 {
     76    Int i;
     77    if (set == NULL)
     78       return -1;
     79    for (i = 0; i < _VKI_NSIG_WORDS; i++)
     80       set->sig[i] = 0;
     81    return 0;
     82 }
     83 
     84 Bool VG_(isemptysigset)( const vki_sigset_t* set )
     85 {
     86    Int i;
     87    vg_assert(set != NULL);
     88    for (i = 0; i < _VKI_NSIG_WORDS; i++) {
     89       if (_VKI_NSIG_BPW * (i + 1) <= (_VKI_MAXSIG + 1)) {
     90          /* Full word check. */
     91          if (set->sig[i] != 0) return False;
     92       }
     93       else {
     94          /* Partial word check. */
     95          ULong mask = (1UL << (_VKI_MAXSIG % _VKI_NSIG_BPW)) - 1;
     96          if ((set->sig[i] & mask) != 0) return False;
     97          break;
     98       }
     99    }
    100    return True;
    101 }
    102 
    103 Bool VG_(isfullsigset)( const vki_sigset_t* set )
    104 {
    105    Int i;
    106    vg_assert(set != NULL);
    107    for (i = 0; i < _VKI_NSIG_WORDS; i++) {
    108       if (_VKI_NSIG_BPW * (i + 1) <= (_VKI_MAXSIG + 1)) {
    109          /* Full word check. */
    110          if (set->sig[i] != ~0) return False;
    111       }
    112       else {
    113          /* Partial word check. */
    114          ULong mask = (1UL << (_VKI_MAXSIG % _VKI_NSIG_BPW)) - 1;
    115          if ((set->sig[i] & mask) != mask) return False;
    116          break;
    117       }
    118    }
    119    return True;
    120 }
    121 
    122 Bool VG_(iseqsigset)( const vki_sigset_t* set1, const vki_sigset_t* set2 )
    123 {
    124    Int i;
    125    vg_assert(set1 != NULL && set2 != NULL);
    126    for (i = 0; i < _VKI_NSIG_WORDS; i++) {
    127       if (_VKI_NSIG_BPW * (i + 1) <= (_VKI_MAXSIG + 1)) {
    128          /* Full word comparison. */
    129          if (set1->sig[i] != set2->sig[i]) return False;
    130       }
    131       else {
    132          /* Partial word comparison. */
    133          ULong mask = (1UL << (_VKI_MAXSIG % _VKI_NSIG_BPW)) - 1;
    134          if ((set1->sig[i] & mask) != (set2->sig[i] & mask)) return False;
    135          break;
    136       }
    137    }
    138    return True;
    139 }
    140 
    141 
    142 Int VG_(sigaddset)( vki_sigset_t* set, Int signum )
    143 {
    144    if (set == NULL)
    145       return -1;
    146    if (signum < 1 || signum > _VKI_NSIG)
    147       return -1;
    148    signum--;
    149    set->sig[signum / _VKI_NSIG_BPW] |= (1ULL << (signum % _VKI_NSIG_BPW));
    150    return 0;
    151 }
    152 
    153 Int VG_(sigdelset)( vki_sigset_t* set, Int signum )
    154 {
    155    if (set == NULL)
    156       return -1;
    157    if (signum < 1 || signum > _VKI_NSIG)
    158       return -1;
    159    signum--;
    160    set->sig[signum / _VKI_NSIG_BPW] &= ~(1ULL << (signum % _VKI_NSIG_BPW));
    161    return 0;
    162 }
    163 
    164 Int VG_(sigismember) ( const vki_sigset_t* set, Int signum )
    165 {
    166    if (set == NULL)
    167       return 0;
    168    if (signum < 1 || signum > _VKI_NSIG)
    169       return 0;
    170    signum--;
    171    if (1 & ((set->sig[signum / _VKI_NSIG_BPW]) >> (signum % _VKI_NSIG_BPW)))
    172       return 1;
    173    else
    174       return 0;
    175 }
    176 
    177 /* Add all signals in src to dst. */
    178 void VG_(sigaddset_from_set)( vki_sigset_t* dst, const vki_sigset_t* src )
    179 {
    180    Int i;
    181    vg_assert(dst != NULL && src != NULL);
    182    for (i = 0; i < _VKI_NSIG_WORDS; i++)
    183       dst->sig[i] |= src->sig[i];
    184 }
    185 
    186 /* Remove all signals in src from dst. */
    187 void VG_(sigdelset_from_set)( vki_sigset_t* dst, const vki_sigset_t* src )
    188 {
    189    Int i;
    190    vg_assert(dst != NULL && src != NULL);
    191    for (i = 0; i < _VKI_NSIG_WORDS; i++)
    192       dst->sig[i] &= ~(src->sig[i]);
    193 }
    194 
    195 /* dst = dst `intersect` src. */
    196 void VG_(sigintersectset)( vki_sigset_t* dst, const vki_sigset_t* src )
    197 {
    198    Int i;
    199    vg_assert(dst != NULL && src != NULL);
    200    for (i = 0; i < _VKI_NSIG_WORDS; i++)
    201       dst->sig[i] &= src->sig[i];
    202 }
    203 
    204 /* dst = ~src */
    205 void VG_(sigcomplementset)( vki_sigset_t* dst, const vki_sigset_t* src )
    206 {
    207    Int i;
    208    vg_assert(dst != NULL && src != NULL);
    209    for (i = 0; i < _VKI_NSIG_WORDS; i++)
    210       dst->sig[i] = ~ src->sig[i];
    211 }
    212 
    213 
    214 /* The functions sigaction, sigprocmask, sigpending and sigsuspend
    215    return 0 on success and -1 on error.
    216 */
    217 Int VG_(sigprocmask)( Int how, const vki_sigset_t* set, vki_sigset_t* oldset)
    218 {
    219 #  if defined(VGO_linux) || defined(VGO_solaris)
    220 #  if defined(__NR_rt_sigprocmask)
    221    SysRes res = VG_(do_syscall4)(__NR_rt_sigprocmask,
    222                                  how, (UWord)set, (UWord)oldset,
    223                                  _VKI_NSIG_WORDS * sizeof(UWord));
    224 #  else
    225    SysRes res = VG_(do_syscall3)(__NR_sigprocmask,
    226                                  how, (UWord)set, (UWord)oldset);
    227 #  endif
    228 
    229 #  elif defined(VGO_darwin)
    230    /* On Darwin, __NR_sigprocmask appears to affect the entire
    231       process, not just this thread.  Hence need to use
    232       __NR___pthread_sigmask instead. */
    233    SysRes res =  VG_(do_syscall3)(__NR___pthread_sigmask,
    234                                   how, (UWord)set, (UWord)oldset);
    235 #  else
    236 #    error "Unknown OS"
    237 #  endif
    238    return sr_isError(res) ? -1 : 0;
    239 }
    240 
    241 
    242 #if defined(VGO_darwin)
    243 /* A helper function for sigaction on Darwin. */
    244 static
    245 void darwin_signal_demux(void* a1, UWord a2, UWord a3, void* a4, void* a5) {
    246    VG_(debugLog)(2, "libcsignal",
    247                     "PRE  demux sig, a2 = %lu, signo = %lu\n", a2, a3);
    248    if (a2 == 1)
    249       ((void(*)(int))a1) (a3);
    250    else
    251       ((void(*)(int,void*,void*))a1) (a3,a4,a5);
    252    VG_(debugLog)(2, "libcsignal",
    253                     "POST demux sig, a2 = %lu, signo = %lu\n", a2, a3);
    254    VG_(do_syscall2)(__NR_sigreturn, (UWord)a5, 0x1E);
    255    /* NOTREACHED */
    256    __asm__ __volatile__("ud2");
    257 }
    258 #endif
    259 
    260 Int VG_(sigaction) ( Int signum,
    261                      const vki_sigaction_toK_t* act,
    262                      vki_sigaction_fromK_t* oldact)
    263 {
    264 #  if defined(VGO_linux)
    265    /* Normal case: vki_sigaction_toK_t and vki_sigaction_fromK_t are
    266       identical types. */
    267    SysRes res = VG_(do_syscall4)(__NR_rt_sigaction,
    268                                  signum, (UWord)act, (UWord)oldact,
    269                                  _VKI_NSIG_WORDS * sizeof(UWord));
    270    return sr_isError(res) ? -1 : 0;
    271 
    272 #  elif defined(VGO_darwin)
    273    /* If we're passing a new action to the kernel, make a copy of the
    274       new action, install our own sa_tramp field in it, and ignore
    275       whatever we were provided with.  This is OK because all the
    276       sigaction requests come from m_signals, and are not directly
    277       what the client program requested, so there is no chance that we
    278       will inadvertently ignore the sa_tramp field requested by the
    279       client.  (In fact m_signals does ignore it when building signal
    280       frames for the client, but that's a completely different
    281       matter).
    282 
    283       If we're receiving an old action from the kernel, be very
    284       paranoid and make sure the kernel doesn't trash bits of memory
    285       that we don't expect it to. */
    286    SysRes res;
    287 
    288    vki_sigaction_toK_t actCopy;
    289    struct {
    290      ULong before[2];
    291      vki_sigaction_fromK_t oa;
    292      ULong after[2];
    293    }
    294    oldactCopy;
    295 
    296    vki_sigaction_toK_t*   real_act;
    297    vki_sigaction_fromK_t* real_oldact;
    298 
    299    real_act    = act    ? &actCopy       : NULL;
    300    real_oldact = oldact ? &oldactCopy.oa : NULL;
    301    VG_(memset)(&oldactCopy, 0x55, sizeof(oldactCopy));
    302    if (real_act) {
    303       *real_act = *act;
    304       real_act->sa_tramp = (void*)&darwin_signal_demux;
    305    }
    306    res = VG_(do_syscall3)(__NR_sigaction,
    307                           signum, (UWord)real_act, (UWord)real_oldact);
    308    if (real_oldact) {
    309       vg_assert(oldactCopy.before[0] == 0x5555555555555555ULL);
    310       vg_assert(oldactCopy.before[1] == 0x5555555555555555ULL);
    311       vg_assert(oldactCopy.after[0]  == 0x5555555555555555ULL);
    312       vg_assert(oldactCopy.after[1]  == 0x5555555555555555ULL);
    313       *oldact = *real_oldact;
    314    }
    315    return sr_isError(res) ? -1 : 0;
    316 
    317 #  elif defined(VGO_solaris)
    318    /* vki_sigaction_toK_t and vki_sigaction_fromK_t are identical types. */
    319    SysRes res = VG_(do_syscall3)(__NR_sigaction,
    320                                  signum, (UWord)act, (UWord)oldact);
    321    return sr_isError(res) ? -1 : 0;
    322 
    323 #  else
    324 #    error "Unsupported OS"
    325 #  endif
    326 }
    327 
    328 
    329 /* See explanation in pub_core_libcsignal.h. */
    330 void
    331 VG_(convert_sigaction_fromK_to_toK)( const vki_sigaction_fromK_t* fromK,
    332                                      /*OUT*/vki_sigaction_toK_t* toK )
    333 {
    334 #  if defined(VGO_linux) || defined(VGO_solaris)
    335    *toK = *fromK;
    336 #  elif defined(VGO_darwin)
    337    toK->ksa_handler = fromK->ksa_handler;
    338    toK->sa_tramp    = NULL; /* the cause of all the difficulty */
    339    toK->sa_mask     = fromK->sa_mask;
    340    toK->sa_flags    = fromK->sa_flags;
    341 #  else
    342 #    error "Unsupported OS"
    343 #  endif
    344 }
    345 
    346 
    347 Int VG_(kill)( Int pid, Int signo )
    348 {
    349 #  if defined(VGO_linux) || defined(VGO_solaris)
    350    SysRes res = VG_(do_syscall2)(__NR_kill, pid, signo);
    351 #  elif defined(VGO_darwin)
    352    SysRes res = VG_(do_syscall3)(__NR_kill,
    353                                  pid, signo, 1/*posix-compliant*/);
    354 #  else
    355 #    error "Unsupported OS"
    356 #  endif
    357    return sr_isError(res) ? -1 : 0;
    358 }
    359 
    360 Int VG_(tkill)( Int lwpid, Int signo )
    361 {
    362 #  if defined(__NR_tkill)
    363    SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
    364    res = VG_(do_syscall2)(__NR_tkill, lwpid, signo);
    365    if (sr_isError(res) && sr_Err(res) == VKI_ENOSYS)
    366       res = VG_(do_syscall2)(__NR_kill, lwpid, signo);
    367    return sr_isError(res) ? -1 : 0;
    368 
    369 #  elif defined(VGO_darwin)
    370    // Note that the __pthread_kill syscall takes a Mach thread, not a pthread.
    371    SysRes res;
    372    res = VG_(do_syscall2)(__NR___pthread_kill, lwpid, signo);
    373    return sr_isError(res) ? -1 : 0;
    374 
    375 #  elif defined(VGO_solaris)
    376    SysRes res;
    377 #     if defined(SOLARIS_LWP_SIGQUEUE_SYSCALL)
    378 #        if defined(SOLARIS_LWP_SIGQUEUE_SYSCALL_TAKES_PID)
    379             res = VG_(do_syscall6)(__NR_lwp_sigqueue, 0, lwpid, signo,
    380                                    0, VKI_SI_LWP, 0);
    381 #        else
    382             res = VG_(do_syscall5)(__NR_lwp_sigqueue, lwpid, signo,
    383                                    0, VKI_SI_LWP, 0);
    384 #        endif
    385 #     else
    386          res = VG_(do_syscall2)(__NR_lwp_kill, lwpid, signo);
    387 #     endif
    388    return sr_isError(res) ? -1 : 0;
    389 
    390 #  else
    391 #    error "Unsupported plat"
    392 #  endif
    393 }
    394 
    395 /* ---------------------- sigtimedwait_zero ----------------------- */
    396 
    397 /* A cut-down version of POSIX sigtimedwait: poll for pending signals
    398    mentioned in the sigset_t, and if any are present, select one
    399    arbitrarily, return its number (which must be > 0), and put
    400    auxiliary info about it in the siginfo_t, and make it
    401    not-pending-any-more.  If none are pending, return zero.  The _zero
    402    refers to the fact that there is zero timeout, so if no signals are
    403    pending it returns immediately.  Perhaps a better name would be
    404    'sigpoll'.  Returns -1 on error, 0 if no signals pending, and n > 0
    405    if signal n was selected.
    406 
    407    The Linux implementation is trivial: do the corresponding syscall.
    408 
    409    The Darwin implementation is horrible and probably broken in a dozen
    410    obscure ways.  I suspect it's only thread-safe because V forces
    411    single-threadedness. */
    412 
    413 /* ---------- sigtimedwait_zero: Linux ----------- */
    414 
    415 #if defined(VGO_linux)
    416 Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
    417                             vki_siginfo_t *info )
    418 {
    419    static const struct vki_timespec zero = { 0, 0 };
    420    SysRes res = VG_(do_syscall4)(__NR_rt_sigtimedwait, (UWord)set, (UWord)info,
    421                                  (UWord)&zero, sizeof(*set));
    422    return sr_isError(res) ? -1 : sr_Res(res);
    423 }
    424 
    425 /* ---------- sigtimedwait_zero: Darwin ----------- */
    426 
    427 #elif defined(VGO_darwin)
    428 
    429 //static void show_set ( HChar* str, const vki_sigset_t* set ) {
    430 //   Int i;
    431 //   VG_(printf)("%s { ", str);
    432 //   for (i = 1; i <= _VKI_NSIG; i++) {
    433 //     if (VG_(sigismember)(set, i))
    434 //         VG_(printf)("%u ", i);
    435 //   }
    436 //   VG_(printf)("}\n");
    437 //}
    438 
    439 /* The general idea is:
    440    - use sigpending to find out which signals are pending
    441    - choose one
    442    - temporarily set its handler to sigtimedwait_zero_handler
    443    - use sigsuspend atomically unblock it and wait for the signal.
    444      Upon return, sigsuspend restores the signal mask to what it
    445      was to start with.
    446    - Restore the handler for the signal to whatever it was before.
    447 */
    448 
    449 /* A signal handler which does nothing (it doesn't need to).  It does
    450    however check that it's not handing a sync signal for which
    451    returning is meaningless. */
    452 static void sigtimedwait_zero_handler ( Int sig )
    453 {
    454    /* XXX this is wrong -- get rid of these.  We could
    455       get _any_ signal here */
    456    vg_assert(sig != VKI_SIGILL);
    457    vg_assert(sig != VKI_SIGSEGV);
    458    vg_assert(sig != VKI_SIGBUS);
    459    vg_assert(sig != VKI_SIGTRAP);
    460    /* do nothing */
    461 }
    462 
    463 Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
    464                             vki_siginfo_t *info )
    465 {
    466   const Bool debug = False;
    467   Int    i, ir;
    468   SysRes sr;
    469   vki_sigset_t pending, blocked, allbutone;
    470   vki_sigaction_toK_t   sa, saved_sa2;
    471   vki_sigaction_fromK_t saved_sa;
    472 
    473   //show_set("STWZ: looking for", set);
    474 
    475   /* Find out what's pending: Darwin sigpending */
    476   sr = VG_(do_syscall1)(__NR_sigpending, (UWord)&pending);
    477   vg_assert(!sr_isError(sr));
    478 
    479   /* don't try for signals not in 'set' */
    480   /* pending = pending `intersect` set */
    481   VG_(sigintersectset)(&pending, (const vki_sigset_t*)set);
    482 
    483   /* don't try for signals not blocked at the moment */
    484   ir = VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &blocked);
    485   vg_assert(ir == 0);
    486 
    487   /* pending = pending `intersect` blocked */
    488   VG_(sigintersectset)(&pending, &blocked);
    489 
    490   /* decide which signal we're going to snarf */
    491   for (i = 1; i < _VKI_NSIG; i++)
    492      if (VG_(sigismember)(&pending,i))
    493         break;
    494 
    495   if (i == _VKI_NSIG)
    496      return 0;
    497 
    498   if (debug)
    499      VG_(debugLog)(0, "libcsignal",
    500                       "sigtimedwait_zero: snarfing signal %d\n", i );
    501 
    502   /* fetch signal i.
    503      pre: i is blocked and pending
    504      pre: we are the only thread running
    505   */
    506   /* Set up alternative signal handler */
    507   VG_(sigfillset)(&sa.sa_mask);
    508   sa.ksa_handler = &sigtimedwait_zero_handler;
    509   sa.sa_flags    = 0;
    510   ir = VG_(sigaction)(i, &sa, &saved_sa);
    511   vg_assert(ir == 0);
    512 
    513   /* Switch signal masks and wait for the signal.  This should happen
    514      immediately, since we've already established it is pending and
    515      blocked. */
    516   VG_(sigfillset)(&allbutone);
    517   VG_(sigdelset)(&allbutone, i);
    518   /* Note: pass the sig mask by value here, not reference (!) */
    519   vg_assert(_VKI_NSIG_WORDS == 1);
    520   sr = VG_(do_syscall3)(__NR_sigsuspend_nocancel,
    521                         (UWord)allbutone.sig[0], 0,0);
    522   if (debug)
    523      VG_(debugLog)(0, "libcsignal",
    524                       "sigtimedwait_zero: sigsuspend got "
    525                       "res: %s %#lx\n",
    526                       sr_isError(sr) ? "FAIL" : "SUCCESS",
    527                       sr_isError(sr) ? sr_Err(sr) : sr_Res(sr));
    528   vg_assert(sr_isError(sr));
    529   vg_assert(sr_Err(sr) == VKI_EINTR);
    530 
    531   /* Restore signal's handler to whatever it was before */
    532   VG_(convert_sigaction_fromK_to_toK)( &saved_sa, &saved_sa2 );
    533   ir = VG_(sigaction)(i, &saved_sa2, NULL);
    534   vg_assert(ir == 0);
    535 
    536   /* This is bogus - we could get more info from the sighandler. */
    537   VG_(memset)( info, 0, sizeof(*info) );
    538   info->si_signo = i;
    539 
    540   return i;
    541 }
    542 
    543 #elif defined(VGO_solaris)
    544 Int VG_(sigtimedwait_zero)( const vki_sigset_t *set, vki_siginfo_t *info )
    545 {
    546    /* Trivial as on Linux. */
    547    static const struct vki_timespec zero = { 0, 0 };
    548    SysRes res = VG_(do_syscall3)(__NR_sigtimedwait, (UWord)set, (UWord)info,
    549                                  (UWord)&zero);
    550    return sr_isError(res) ? -1 : sr_Res(res);
    551 }
    552 
    553 #else
    554 #  error "Unknown OS"
    555 #endif
    556 
    557 /*--------------------------------------------------------------------*/
    558 /*--- end                                                          ---*/
    559 /*--------------------------------------------------------------------*/
    560