• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
f(bool poisoned,int n,...)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 
SignalHandler(int signo)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 
main()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