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
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 
VG_(sigfillset)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 
VG_(sigemptyset)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 
VG_(isemptysigset)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 = ((ULong)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 
VG_(isfullsigset)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 = ((ULong)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 
VG_(iseqsigset)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 = ((ULong)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 
VG_(sigaddset)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 
VG_(sigdelset)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 
VG_(sigismember)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. */
VG_(sigaddset_from_set)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. */
VG_(sigdelset_from_set)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. */
VG_(sigintersectset)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 */
VG_(sigcomplementset)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 */
VG_(sigprocmask)217 Int VG_(sigprocmask)( Int how, const vki_sigset_t* set, vki_sigset_t* oldset)
218 {
219 #  if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_dragonfly)
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
darwin_signal_demux(void * a1,UWord a2,UWord a3,void * a4,void * a5)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 
VG_(sigaction)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 #  elif defined(VGO_dragonfly)
324    SysRes res = VG_(do_syscall3)(__NR_sigaction,
325                                  signum, (UWord)act, (UWord)oldact);
326    return sr_isError(res) ? -1 : 0;
327 
328 
329 #  else
330 #    error "Unsupported OS"
331 #  endif
332 }
333 
334 
335 /* See explanation in pub_core_libcsignal.h. */
336 void
VG_(convert_sigaction_fromK_to_toK)337 VG_(convert_sigaction_fromK_to_toK)( const vki_sigaction_fromK_t* fromK,
338                                      /*OUT*/vki_sigaction_toK_t* toK )
339 {
340 #  if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_dragonfly)
341    *toK = *fromK;
342 #  elif defined(VGO_darwin)
343    toK->ksa_handler = fromK->ksa_handler;
344    toK->sa_tramp    = NULL; /* the cause of all the difficulty */
345    toK->sa_mask     = fromK->sa_mask;
346    toK->sa_flags    = fromK->sa_flags;
347 #  else
348 #    error "Unsupported OS"
349 #  endif
350 }
351 
352 
VG_(kill)353 Int VG_(kill)( Int pid, Int signo )
354 {
355 #  if defined(VGO_linux) || defined(VGO_solaris)
356    SysRes res = VG_(do_syscall2)(__NR_kill, pid, signo);
357 #  elif defined(VGO_darwin) || defined(VGO_dragonfly)
358    SysRes res = VG_(do_syscall3)(__NR_kill,
359                                  pid, signo, 1/*posix-compliant*/);
360 #  else
361 #    error "Unsupported OS"
362 #  endif
363    return sr_isError(res) ? -1 : 0;
364 }
365 
VG_(tkill)366 Int VG_(tkill)( Int lwpid, Int signo )
367 {
368 #  if defined(__NR_tkill)
369    SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
370    res = VG_(do_syscall2)(__NR_tkill, lwpid, signo);
371    if (sr_isError(res) && sr_Err(res) == VKI_ENOSYS)
372       res = VG_(do_syscall2)(__NR_kill, lwpid, signo);
373    return sr_isError(res) ? -1 : 0;
374 
375 #  elif defined(VGO_darwin)
376    // Note that the __pthread_kill syscall takes a Mach thread, not a pthread.
377    SysRes res;
378    res = VG_(do_syscall2)(__NR___pthread_kill, lwpid, signo);
379    return sr_isError(res) ? -1 : 0;
380 
381 #  elif defined(VGO_solaris)
382    SysRes res;
383 #     if defined(SOLARIS_LWP_SIGQUEUE_SYSCALL)
384 #        if defined(SOLARIS_LWP_SIGQUEUE_SYSCALL_TAKES_PID)
385             res = VG_(do_syscall6)(__NR_lwp_sigqueue, 0, lwpid, signo,
386                                    0, VKI_SI_LWP, 0);
387 #        else
388             res = VG_(do_syscall5)(__NR_lwp_sigqueue, lwpid, signo,
389                                    0, VKI_SI_LWP, 0);
390 #        endif
391 #     else
392          res = VG_(do_syscall2)(__NR_lwp_kill, lwpid, signo);
393 #     endif
394    return sr_isError(res) ? -1 : 0;
395 
396 
397 #  elif defined(VGO_dragonfly)
398    SysRes res;
399    res = VG_(do_syscall3)(__NR_lwp_kill, -1, lwpid, signo);
400    return sr_isError(res) ? -1 : 0;
401 
402 #  else
403 #    error "Unsupported plat"
404 #  endif
405 }
406 
407 /* ---------------------- sigtimedwait_zero ----------------------- */
408 
409 /* A cut-down version of POSIX sigtimedwait: poll for pending signals
410    mentioned in the sigset_t, and if any are present, select one
411    arbitrarily, return its number (which must be > 0), and put
412    auxiliary info about it in the siginfo_t, and make it
413    not-pending-any-more.  If none are pending, return zero.  The _zero
414    refers to the fact that there is zero timeout, so if no signals are
415    pending it returns immediately.  Perhaps a better name would be
416    'sigpoll'.  Returns -1 on error, 0 if no signals pending, and n > 0
417    if signal n was selected.
418 
419    The Linux implementation is trivial: do the corresponding syscall.
420 
421    The Darwin implementation is horrible and probably broken in a dozen
422    obscure ways.  I suspect it's only thread-safe because V forces
423    single-threadedness. */
424 
425 /* ---------- sigtimedwait_zero: Linux ----------- */
426 
427 #if defined(VGO_linux)
VG_(sigtimedwait_zero)428 Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
429                             vki_siginfo_t *info )
430 {
431    static const struct vki_timespec zero = { 0, 0 };
432    SysRes res = VG_(do_syscall4)(__NR_rt_sigtimedwait, (UWord)set, (UWord)info,
433                                  (UWord)&zero, sizeof(*set));
434    return sr_isError(res) ? -1 : sr_Res(res);
435 }
436 
437 /* ---------- sigtimedwait_zero: Darwin ----------- */
438 
439 #elif defined(VGO_darwin)
440 
441 //static void show_set ( HChar* str, const vki_sigset_t* set ) {
442 //   Int i;
443 //   VG_(printf)("%s { ", str);
444 //   for (i = 1; i <= _VKI_NSIG; i++) {
445 //     if (VG_(sigismember)(set, i))
446 //         VG_(printf)("%u ", i);
447 //   }
448 //   VG_(printf)("}\n");
449 //}
450 
451 /* The general idea is:
452    - use sigpending to find out which signals are pending
453    - choose one
454    - temporarily set its handler to sigtimedwait_zero_handler
455    - use sigsuspend atomically unblock it and wait for the signal.
456      Upon return, sigsuspend restores the signal mask to what it
457      was to start with.
458    - Restore the handler for the signal to whatever it was before.
459 */
460 
461 /* A signal handler which does nothing (it doesn't need to).  It does
462    however check that it's not handing a sync signal for which
463    returning is meaningless. */
sigtimedwait_zero_handler(Int sig)464 static void sigtimedwait_zero_handler ( Int sig )
465 {
466    /* XXX this is wrong -- get rid of these.  We could
467       get _any_ signal here */
468    vg_assert(sig != VKI_SIGILL);
469    vg_assert(sig != VKI_SIGSEGV);
470    vg_assert(sig != VKI_SIGBUS);
471    vg_assert(sig != VKI_SIGTRAP);
472    /* do nothing */
473 }
474 
VG_(sigtimedwait_zero)475 Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
476                             vki_siginfo_t *info )
477 {
478   const Bool debug = False;
479   Int    i, ir;
480   SysRes sr;
481   vki_sigset_t pending, blocked, allbutone;
482   vki_sigaction_toK_t   sa, saved_sa2;
483   vki_sigaction_fromK_t saved_sa;
484 
485   //show_set("STWZ: looking for", set);
486 
487   /* Find out what's pending: Darwin sigpending */
488   sr = VG_(do_syscall1)(__NR_sigpending, (UWord)&pending);
489   vg_assert(!sr_isError(sr));
490 
491   /* don't try for signals not in 'set' */
492   /* pending = pending `intersect` set */
493   VG_(sigintersectset)(&pending, (const vki_sigset_t*)set);
494 
495   /* don't try for signals not blocked at the moment */
496   ir = VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &blocked);
497   vg_assert(ir == 0);
498 
499   /* pending = pending `intersect` blocked */
500   VG_(sigintersectset)(&pending, &blocked);
501 
502   /* decide which signal we're going to snarf */
503   for (i = 1; i < _VKI_NSIG; i++)
504      if (VG_(sigismember)(&pending,i))
505         break;
506 
507   if (i == _VKI_NSIG)
508      return 0;
509 
510   if (debug)
511      VG_(debugLog)(0, "libcsignal",
512                       "sigtimedwait_zero: snarfing signal %d\n", i );
513 
514   /* fetch signal i.
515      pre: i is blocked and pending
516      pre: we are the only thread running
517   */
518   /* Set up alternative signal handler */
519   VG_(sigfillset)(&sa.sa_mask);
520   sa.ksa_handler = &sigtimedwait_zero_handler;
521   sa.sa_flags    = 0;
522   ir = VG_(sigaction)(i, &sa, &saved_sa);
523   vg_assert(ir == 0);
524 
525   /* Switch signal masks and wait for the signal.  This should happen
526      immediately, since we've already established it is pending and
527      blocked. */
528   VG_(sigfillset)(&allbutone);
529   VG_(sigdelset)(&allbutone, i);
530   /* Note: pass the sig mask by value here, not reference (!) */
531   vg_assert(_VKI_NSIG_WORDS == 1);
532   sr = VG_(do_syscall3)(__NR_sigsuspend_nocancel,
533                         (UWord)allbutone.sig[0], 0,0);
534   if (debug)
535      VG_(debugLog)(0, "libcsignal",
536                       "sigtimedwait_zero: sigsuspend got "
537                       "res: %s %#lx\n",
538                       sr_isError(sr) ? "FAIL" : "SUCCESS",
539                       sr_isError(sr) ? sr_Err(sr) : sr_Res(sr));
540   vg_assert(sr_isError(sr));
541   vg_assert(sr_Err(sr) == VKI_EINTR);
542 
543   /* Restore signal's handler to whatever it was before */
544   VG_(convert_sigaction_fromK_to_toK)( &saved_sa, &saved_sa2 );
545   ir = VG_(sigaction)(i, &saved_sa2, NULL);
546   vg_assert(ir == 0);
547 
548   /* This is bogus - we could get more info from the sighandler. */
549   VG_(memset)( info, 0, sizeof(*info) );
550   info->si_signo = i;
551 
552   return i;
553 }
554 
555 #elif defined(VGO_solaris)
VG_(sigtimedwait_zero)556 Int VG_(sigtimedwait_zero)( const vki_sigset_t *set, vki_siginfo_t *info )
557 {
558    /* Trivial as on Linux. */
559    static const struct vki_timespec zero = { 0, 0 };
560    SysRes res = VG_(do_syscall3)(__NR_sigtimedwait, (UWord)set, (UWord)info,
561                                  (UWord)&zero);
562    return sr_isError(res) ? -1 : sr_Res(res);
563 }
564 
565 #elif defined(VGO_dragonfly)
566 
VG_(sigtimedwait_zero)567 Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
568                             vki_siginfo_t *info )
569 {
570   static const struct vki_timespec zero = { 0, 0 };
571 
572   SysRes res = VG_(do_syscall3)(__NR_sigtimedwait, (UWord)set, (UWord)info,
573 		  (UWord)&zero);
574 
575   return sr_isError(res) ? -1 : sr_Res(res);
576 }
577 
578 #else
579 #  error "Unknown OS"
580 #endif
581 
582 /*--------------------------------------------------------------------*/
583 /*--- end                                                          ---*/
584 /*--------------------------------------------------------------------*/
585