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@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
43STATIC_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
64Int 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
74Int 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
84Bool 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
103Bool 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
122Bool 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
142Int 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
153Int 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
164Int 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. */
178void 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. */
187void 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. */
196void 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 */
205void 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*/
217Int 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. */
244static
245void 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
260Int 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. */
330void
331VG_(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
347Int 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
360Int 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)
416Int 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. */
452static 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
463Int 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)
544Int 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