Home | History | Annotate | Download | only in msan
      1 // RUN: %clangxx_msan -std=c++11 -O0 %s -o %t && %run %t
      2 //
      3 // Test that va_arg shadow from a signal handler does not leak outside.
      4 
      5 #include <signal.h>
      6 #include <stdarg.h>
      7 #include <sanitizer/msan_interface.h>
      8 #include <assert.h>
      9 #include <sys/time.h>
     10 #include <stdio.h>
     11 
     12 const int kSigCnt = 200;
     13 
     14 void f(bool poisoned, int n, ...) {
     15   va_list vl;
     16   va_start(vl, n);
     17   for (int i = 0; i < n; ++i) {
     18     void *p = va_arg(vl, void *);
     19     if (!poisoned)
     20       assert(__msan_test_shadow(&p, sizeof(p)) == -1);
     21   }
     22   va_end(vl);
     23 }
     24 
     25 int sigcnt;
     26 
     27 void SignalHandler(int signo) {
     28   assert(signo == SIGPROF);
     29   void *p;
     30   void **volatile q = &p;
     31   f(true, 10,
     32     *q, *q, *q, *q, *q,
     33     *q, *q, *q, *q, *q);
     34   ++sigcnt;
     35 }
     36 
     37 int main() {
     38   signal(SIGPROF, SignalHandler);
     39 
     40   itimerval itv;
     41   itv.it_interval.tv_sec = 0;
     42   itv.it_interval.tv_usec = 100;
     43   itv.it_value.tv_sec = 0;
     44   itv.it_value.tv_usec = 100;
     45   setitimer(ITIMER_PROF, &itv, NULL);
     46 
     47   void *p;
     48   void **volatile q = &p;
     49 
     50   do {
     51     f(false, 20,
     52       nullptr, nullptr, nullptr, nullptr, nullptr,
     53       nullptr, nullptr, nullptr, nullptr, nullptr,
     54       nullptr, nullptr, nullptr, nullptr, nullptr,
     55       nullptr, nullptr, nullptr, nullptr, nullptr);
     56     f(true, 20,
     57       *q, *q, *q, *q, *q,
     58       *q, *q, *q, *q, *q,
     59       *q, *q, *q, *q, *q,
     60       *q, *q, *q, *q, *q);
     61   } while (sigcnt < kSigCnt);
     62 
     63   itv.it_interval.tv_sec = 0;
     64   itv.it_interval.tv_usec = 0;
     65   itv.it_value.tv_sec = 0;
     66   itv.it_value.tv_usec = 0;
     67   setitimer(ITIMER_PROF, &itv, NULL);
     68 
     69   signal(SIGPROF, SIG_DFL);
     70   return 0;
     71 }
     72