1 | // RUN: %clangxx_msan -fno-sanitize-memory-param-retval -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 | // Reported deadly signal due to stack-overflow |
6 | // XFAIL: target={{.*netbsd.*}} |
7 | |
8 | #include <signal.h> |
9 | #include <stdarg.h> |
10 | #include <sanitizer/msan_interface.h> |
11 | #include <assert.h> |
12 | #include <sys/time.h> |
13 | #include <stdio.h> |
14 | |
15 | const int kSigCnt = 200; |
16 | |
17 | void f(bool poisoned, int n, ...) { |
18 | va_list vl; |
19 | va_start(vl, n); |
20 | for (int i = 0; i < n; ++i) { |
21 | void *p = va_arg(vl, void *); |
22 | if (!poisoned) |
23 | assert(__msan_test_shadow(&p, sizeof(p)) == -1); |
24 | } |
25 | va_end(vl); |
26 | } |
27 | |
28 | int sigcnt; |
29 | |
30 | void SignalHandler(int signo) { |
31 | assert(signo == SIGPROF); |
32 | void *p; |
33 | void **volatile q = &p; |
34 | f(poisoned: true, n: 10, |
35 | *q, *q, *q, *q, *q, |
36 | *q, *q, *q, *q, *q); |
37 | ++sigcnt; |
38 | } |
39 | |
40 | int main() { |
41 | signal(SIGPROF, handler: SignalHandler); |
42 | |
43 | itimerval itv; |
44 | itv.it_interval.tv_sec = 0; |
45 | itv.it_interval.tv_usec = 100; |
46 | itv.it_value.tv_sec = 0; |
47 | itv.it_value.tv_usec = 100; |
48 | setitimer(ITIMER_PROF, new: &itv, NULL); |
49 | |
50 | void *p; |
51 | void **volatile q = &p; |
52 | |
53 | do { |
54 | f(poisoned: false, n: 20, |
55 | nullptr, nullptr, nullptr, nullptr, nullptr, |
56 | nullptr, nullptr, nullptr, nullptr, nullptr, |
57 | nullptr, nullptr, nullptr, nullptr, nullptr, |
58 | nullptr, nullptr, nullptr, nullptr, nullptr); |
59 | f(poisoned: true, n: 20, |
60 | *q, *q, *q, *q, *q, |
61 | *q, *q, *q, *q, *q, |
62 | *q, *q, *q, *q, *q, |
63 | *q, *q, *q, *q, *q); |
64 | } while (sigcnt < kSigCnt); |
65 | |
66 | itv.it_interval.tv_sec = 0; |
67 | itv.it_interval.tv_usec = 0; |
68 | itv.it_value.tv_sec = 0; |
69 | itv.it_value.tv_usec = 0; |
70 | setitimer(ITIMER_PROF, new: &itv, NULL); |
71 | |
72 | signal(SIGPROF, SIG_DFL); |
73 | return 0; |
74 | } |
75 | |