75 lines · cpp
1// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -std=c++11 -O0 %s -o %t && %run %t2//3// Test that va_arg shadow from a signal handler does not leak outside.4 5// Reported deadly signal due to stack-overflow6// 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 15const int kSigCnt = 200;16 17void 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 28int sigcnt;29 30void SignalHandler(int signo) {31 assert(signo == SIGPROF);32 void *p;33 void **volatile q = &p;34 f(true, 10,35 *q, *q, *q, *q, *q,36 *q, *q, *q, *q, *q);37 ++sigcnt;38}39 40int main() {41 signal(SIGPROF, 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, &itv, NULL);49 50 void *p;51 void **volatile q = &p;52 53 do {54 f(false, 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(true, 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, &itv, NULL);71 72 signal(SIGPROF, SIG_DFL);73 return 0;74}75