251 lines · cpp
1// Test how we produce the scariness score.2 3// UAR Mode: runtime4// Case 26 loads a __asan_poison_memory_region-poisoned local variable, which is5// only instrumented when StackSafetyAnalysis is disabled.6// RUN: %clangxx_asan -O0 -mllvm -asan-use-stack-safety=0 %s -o %t7// On OSX and Windows, alloc_dealloc_mismatch=1 isn't 100% reliable, so it's8// off by default. It's safe for these tests, though, so we turn it on.9// RUN: %export_asan_opts=symbolize=0:detect_stack_use_after_return=1:handle_abort=1:print_scariness=1:alloc_dealloc_mismatch=110// Make sure the stack is limited (may not be the default under GNU make)11// RUN: ulimit -s 409612// RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK113// RUN: not %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK214// RUN: not %run %t 3 2>&1 | FileCheck %s --check-prefix=CHECK315// RUN: not %run %t 4 2>&1 | FileCheck %s --check-prefix=CHECK416// RUN: not %run %t 5 2>&1 | FileCheck %s --check-prefix=CHECK517// RUN: not %run %t 6 2>&1 | FileCheck %s --check-prefix=CHECK618// RUN: not %run %t 7 2>&1 | FileCheck %s --check-prefix=CHECK719// RUN: not %run %t 8 2>&1 | FileCheck %s --check-prefix=CHECK820// RUN: not %run %t 9 2>&1 | FileCheck %s --check-prefix=CHECK921// RUN: not %run %t 10 2>&1 | FileCheck %s --check-prefix=CHECK1022// RUN: not %run %t 11 2>&1 | FileCheck %s --check-prefix=CHECK1123// RUN: not %run %t 12 2>&1 | FileCheck %s --check-prefix=CHECK1224// RUN: not %run %t 13 2>&1 | FileCheck %s --check-prefix=CHECK1325// RUN: not %run %t 14 2>&1 | FileCheck %s --check-prefix=CHECK1426// RUN: not %run %t 15 2>&1 | FileCheck %s --check-prefix=CHECK1527// RUN: not %run %t 16 2>&1 | FileCheck %s --check-prefix=CHECK1628// RUN: not %run %t 17 2>&1 | FileCheck %s --check-prefix=CHECK1729// RUN: not %run %t 18 2>&1 | FileCheck %s --check-prefix=CHECK1830// RUN: not %run %t 19 2>&1 | FileCheck %s --check-prefix=CHECK1931// RUN: not %run %t 20 2>&1 | FileCheck %s --check-prefix=CHECK2032// RUN: not %run %t 21 2>&1 | FileCheck %s --check-prefix=CHECK2133// RUN: not %run %t 22 2>&1 | FileCheck %s --check-prefix=CHECK2234// RUN: not %run %t 23 2>&1 | FileCheck %s --check-prefix=CHECK2335// RUN: not %run %t 24 2>&1 | FileCheck %s --check-prefix=CHECK2436// RUN: not %run %t 25 2>&1 | FileCheck %s --check-prefix=CHECK2537// RUN: not %run %t 26 2>&1 | FileCheck %s --check-prefix=CHECK2638// RUN: not %run %t 27 2>&1 | FileCheck %s --check-prefix=CHECK2739//40// UAR Mode: always41// RUN: %clangxx_asan -O0 %s -o %t -fsanitize-address-use-after-return=always -mllvm -asan-use-stack-safety=042// On OSX and Windows, alloc_dealloc_mismatch=1 isn't 100% reliable, so it's43// off by default. It's safe for these tests, though, so we turn it on.44// RUN: %export_asan_opts=symbolize=0:handle_abort=1:print_scariness=1:alloc_dealloc_mismatch=145// Make sure the stack is limited (may not be the default under GNU make)46// RUN: ulimit -s 409647// RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK148// RUN: not %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK249// RUN: not %run %t 3 2>&1 | FileCheck %s --check-prefix=CHECK350// RUN: not %run %t 4 2>&1 | FileCheck %s --check-prefix=CHECK451// RUN: not %run %t 5 2>&1 | FileCheck %s --check-prefix=CHECK552// RUN: not %run %t 6 2>&1 | FileCheck %s --check-prefix=CHECK653// RUN: not %run %t 7 2>&1 | FileCheck %s --check-prefix=CHECK754// RUN: not %run %t 8 2>&1 | FileCheck %s --check-prefix=CHECK855// RUN: not %run %t 9 2>&1 | FileCheck %s --check-prefix=CHECK956// RUN: not %run %t 10 2>&1 | FileCheck %s --check-prefix=CHECK1057// RUN: not %run %t 11 2>&1 | FileCheck %s --check-prefix=CHECK1158// RUN: not %run %t 12 2>&1 | FileCheck %s --check-prefix=CHECK1259// RUN: not %run %t 13 2>&1 | FileCheck %s --check-prefix=CHECK1360// RUN: not %run %t 14 2>&1 | FileCheck %s --check-prefix=CHECK1461// RUN: not %run %t 15 2>&1 | FileCheck %s --check-prefix=CHECK1562// RUN: not %run %t 16 2>&1 | FileCheck %s --check-prefix=CHECK1663// RUN: not %run %t 17 2>&1 | FileCheck %s --check-prefix=CHECK1764// RUN: not %run %t 18 2>&1 | FileCheck %s --check-prefix=CHECK1865// RUN: not %run %t 19 2>&1 | FileCheck %s --check-prefix=CHECK1966// RUN: not %run %t 20 2>&1 | FileCheck %s --check-prefix=CHECK2067// RUN: not %run %t 21 2>&1 | FileCheck %s --check-prefix=CHECK2168// RUN: not %run %t 22 2>&1 | FileCheck %s --check-prefix=CHECK2269// RUN: not %run %t 23 2>&1 | FileCheck %s --check-prefix=CHECK2370// RUN: not %run %t 24 2>&1 | FileCheck %s --check-prefix=CHECK2471// RUN: not %run %t 25 2>&1 | FileCheck %s --check-prefix=CHECK2572// RUN: not %run %t 26 2>&1 | FileCheck %s --check-prefix=CHECK2673// RUN: not %run %t 27 2>&1 | FileCheck %s --check-prefix=CHECK2774// Parts of the test are too platform-specific:75// REQUIRES: x86_64-target-arch76// REQUIRES: shell77#include <stdlib.h>78#include <stdio.h>79#include <string.h>80#include <algorithm>81 82#include <sanitizer/asan_interface.h>83 84enum ReadOrWrite { Read = 0, Write = 1 };85 86struct S32 {87 char x[32];88};89 90template<class T>91void HeapBuferOverflow(int Idx, ReadOrWrite w) {92 T *t = new T[100];93 static T sink;94 if (w)95 t[100 + Idx] = T();96 else97 sink = t[100 + Idx];98 delete [] t;99}100 101template<class T>102void HeapUseAfterFree(int Idx, ReadOrWrite w) {103 T *t = new T[100];104 static T sink;105 sink = t[0];106 delete [] t;107 if (w)108 t[Idx] = T();109 else110 sink = t[Idx];111}112 113template<class T>114void StackBufferOverflow(int Idx, ReadOrWrite w) {115 T t[100];116 static T sink;117 sink = t[Idx];118 if (w)119 t[100 + Idx] = T();120 else121 sink = t[100 + Idx];122}123 124template<class T>125T *LeakStack() {126 T t[100];127 static volatile T *x;128 x = &t[0];129 return (T*)x;130}131 132template<class T>133void StackUseAfterReturn(int Idx, ReadOrWrite w) {134 static T sink;135 T *t = LeakStack<T>();136 if (w)137 t[100 + Idx] = T();138 else139 sink = t[100 + Idx];140}141 142char g1[100];143short g2[100];144int g4[100];145int64_t g8[100];146S32 gm[100];147 148void DoubleFree() {149 int *x = new int;150 static volatile int two = 2;151 for (int i = 0; i < two; i++)152 delete x;153}154 155void StackOverflow(int Idx) {156 int some_stack[256];157 static volatile int *x;158 x = &some_stack[0];159 if (Idx > 0)160 StackOverflow(Idx - 1);161}162 163void UseAfterPoison() {164 int buf[100];165 __asan_poison_memory_region(buf, sizeof(buf));166 static volatile int sink;167 sink = buf[42];168}169 170int main(int argc, char **argv) {171 size_t scale;172 size_t offset;173 __asan_get_shadow_mapping(&scale, &offset);174 size_t grain = 1 << scale;175 176 char arr[100];177 static volatile int zero = 0;178 static volatile int *zero_ptr = 0;179 static volatile int *wild_addr = (int*)0x10000000; // System-dependent.180 if (argc != 2) return 1;181 int kind = atoi(argv[1]);182 switch (kind) {183 case 1: HeapBuferOverflow<char>(0, Read); break;184 case 2: HeapBuferOverflow<int>(0, Read); break;185 case 3: HeapBuferOverflow<short>(0, Write); break;186 case 4: HeapBuferOverflow<int64_t>(187 2 * std::max(1, (int)(grain / sizeof(int64_t))), Write); break;188 case 5: HeapBuferOverflow<S32>(4, Write); break;189 case 6: HeapUseAfterFree<char>(0, Read); break;190 case 7: HeapUseAfterFree<int>(0, Write); break;191 case 8: HeapUseAfterFree<int64_t>(0, Read); break;192 case 9: HeapUseAfterFree<S32>(0, Write); break;193 case 10: StackBufferOverflow<char>(0, Write); break;194 case 11: StackBufferOverflow<int64_t>(0, Read); break;195 case 12:196 if (scale <= 3) {197 StackBufferOverflow<int>(16, Write);198 } else {199 // At large shadow granularity, there is not enough redzone200 // between stack elements to detect far-from-bounds. Pretend201 // that this test passes.202 fprintf(stderr, "SCARINESS: 61 "203 "(4-byte-write-stack-buffer-overflow-far-from-bounds)\n");204 return 1;205 }206 break;207 case 13: StackUseAfterReturn<char>(0, Read); break;208 case 14: StackUseAfterReturn<S32>(0, Write); break;209 case 15: g1[zero + 100] = 0; break;210 case 16: gm[0] = gm[zero + 100 + 1]; break;211 case 17: DoubleFree(); break;212 case 18: StackOverflow(1000000); break;213 case 19: *zero_ptr = 0; break;214 case 20: *wild_addr = 0; break;215 case 21: zero = *wild_addr; break;216 case 22: ((void (*)(void))wild_addr)(); break;217 case 23: delete (new int[10]); break;218 case 24: free((char*)malloc(100) + 10); break;219 case 25: memcpy(arr, arr+10, 20); break;220 case 26: UseAfterPoison(); break;221 case 27: abort();222 // CHECK1: SCARINESS: 12 (1-byte-read-heap-buffer-overflow)223 // CHECK2: SCARINESS: 17 (4-byte-read-heap-buffer-overflow)224 // CHECK3: SCARINESS: 33 (2-byte-write-heap-buffer-overflow)225 // CHECK4: SCARINESS: 52 (8-byte-write-heap-buffer-overflow-far-from-bounds)226 // CHECK5: SCARINESS: 55 (multi-byte-write-heap-buffer-overflow-far-from-bounds)227 // CHECK6: SCARINESS: 40 (1-byte-read-heap-use-after-free)228 // CHECK7: SCARINESS: 46 (4-byte-write-heap-use-after-free)229 // CHECK8: SCARINESS: 51 (8-byte-read-heap-use-after-free)230 // CHECK9: SCARINESS: 55 (multi-byte-write-heap-use-after-free)231 // CHECK10: SCARINESS: 46 (1-byte-write-stack-buffer-overflow)232 // CHECK11: SCARINESS: 38 (8-byte-read-stack-buffer-overflow)233 // CHECK12: SCARINESS: 61 (4-byte-write-stack-buffer-overflow-far-from-bounds)234 // CHECK13: SCARINESS: 50 (1-byte-read-stack-use-after-return)235 // CHECK14: SCARINESS: 65 (multi-byte-write-stack-use-after-return)236 // CHECK15: SCARINESS: 31 (1-byte-write-global-buffer-overflow)237 // CHECK16: SCARINESS: 36 (multi-byte-read-global-buffer-overflow-far-from-bounds)238 // CHECK17: SCARINESS: 42 (double-free)239 // CHECK18: SCARINESS: 10 (stack-overflow)240 // CHECK19: SCARINESS: 10 (null-deref)241 // CHECK20: SCARINESS: 30 (wild-addr-write)242 // CHECK21: SCARINESS: 20 (wild-addr-read)243 // CHECK22: SCARINESS: 60 (wild-jump)244 // CHECK23: SCARINESS: 10 (alloc-dealloc-mismatch)245 // CHECK24: SCARINESS: 40 (bad-free)246 // CHECK25: SCARINESS: 10 (memcpy-param-overlap)247 // CHECK26: SCARINESS: 27 (4-byte-read-use-after-poison)248 // CHECK27: SCARINESS: 10 (signal)249 }250}251