Home | History | Annotate | Download | only in Linux
      1 // Check that ASan plays well with easy cases of makecontext/swapcontext.
      2 
      3 // RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | FileCheck %s
      4 // RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | FileCheck %s
      5 // RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | FileCheck %s
      6 // RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | FileCheck %s
      7 // RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | FileCheck %s
      8 // RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | FileCheck %s
      9 // RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | FileCheck %s
     10 // RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | FileCheck %s
     11 
     12 #include <stdio.h>
     13 #include <ucontext.h>
     14 #include <unistd.h>
     15 
     16 ucontext_t orig_context;
     17 ucontext_t child_context;
     18 
     19 void Child(int mode) {
     20   char x[32] = {0};  // Stack gets poisoned.
     21   printf("Child: %p\n", x);
     22   // (a) Do nothing, just return to parent function.
     23   // (b) Jump into the original function. Stack remains poisoned unless we do
     24   //     something.
     25   if (mode == 1) {
     26     if (swapcontext(&child_context, &orig_context) < 0) {
     27       perror("swapcontext");
     28       _exit(0);
     29     }
     30   }
     31 }
     32 
     33 int Run(int arg, int mode) {
     34   const int kStackSize = 1 << 20;
     35   char child_stack[kStackSize + 1];
     36   printf("Child stack: %p\n", child_stack);
     37   // Setup child context.
     38   getcontext(&child_context);
     39   child_context.uc_stack.ss_sp = child_stack;
     40   child_context.uc_stack.ss_size = kStackSize / 2;
     41   if (mode == 0) {
     42     child_context.uc_link = &orig_context;
     43   }
     44   makecontext(&child_context, (void (*)())Child, 1, mode);
     45   if (swapcontext(&orig_context, &child_context) < 0) {
     46     perror("swapcontext");
     47     return 0;
     48   }
     49   // Touch childs's stack to make sure it's unpoisoned.
     50   for (int i = 0; i < kStackSize; i++) {
     51     child_stack[i] = i;
     52   }
     53   return child_stack[arg];
     54 }
     55 
     56 int main(int argc, char **argv) {
     57   // CHECK: WARNING: ASan doesn't fully support makecontext/swapcontext
     58   int ret = 0;
     59   ret += Run(argc - 1, 0);
     60   printf("Test1 passed\n");
     61   // CHECK: Test1 passed
     62   ret += Run(argc - 1, 1);
     63   printf("Test2 passed\n");
     64   // CHECK: Test2 passed
     65   return ret;
     66 }
     67