]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/hwasan/TestCases/allocator_returns_null.cc
Vendor import of compiler-rt trunk r338150:
[FreeBSD/FreeBSD.git] / test / hwasan / TestCases / allocator_returns_null.cc
1 // Test the behavior of malloc/calloc/realloc/new when the allocation size
2 // exceeds the HWASan allocator's max allowed one.
3 // By default (allocator_may_return_null=0) the process should crash. With
4 // allocator_may_return_null=1 the allocator should return 0 and set errno to
5 // the appropriate error code.
6 //
7 // RUN: %clangxx_hwasan -O0 %s -o %t
8 // RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH
9 // RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 \
10 // RUN:   | FileCheck %s --check-prefix=CHECK-mCRASH
11 // RUN: %env_hwasan_opts=allocator_may_return_null=1     %run %t malloc 2>&1 \
12 // RUN:   | FileCheck %s --check-prefix=CHECK-mNULL
13 // RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 \
14 // RUN:   | FileCheck %s --check-prefix=CHECK-cCRASH
15 // RUN: %env_hwasan_opts=allocator_may_return_null=1     %run %t calloc 2>&1 \
16 // RUN:   | FileCheck %s --check-prefix=CHECK-cNULL
17 // RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 \
18 // RUN:   | FileCheck %s --check-prefix=CHECK-coCRASH
19 // RUN: %env_hwasan_opts=allocator_may_return_null=1     %run %t calloc-overflow 2>&1 \
20 // RUN:   | FileCheck %s --check-prefix=CHECK-coNULL
21 // RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 \
22 // RUN:   | FileCheck %s --check-prefix=CHECK-rCRASH
23 // RUN: %env_hwasan_opts=allocator_may_return_null=1     %run %t realloc 2>&1 \
24 // RUN:   | FileCheck %s --check-prefix=CHECK-rNULL
25 // RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \
26 // RUN:   | FileCheck %s --check-prefix=CHECK-mrCRASH
27 // RUN: %env_hwasan_opts=allocator_may_return_null=1     %run %t realloc-after-malloc 2>&1 \
28 // RUN:   | FileCheck %s --check-prefix=CHECK-mrNULL
29 // RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t new 2>&1 \
30 // RUN:   | FileCheck %s --check-prefix=CHECK-nCRASH
31 // RUN: %env_hwasan_opts=allocator_may_return_null=1 not %run %t new 2>&1 \
32 // RUN:   | FileCheck %s --check-prefix=CHECK-nCRASH-OOM
33 // RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \
34 // RUN:   | FileCheck %s --check-prefix=CHECK-nnCRASH
35 // RUN: %env_hwasan_opts=allocator_may_return_null=1     %run %t new-nothrow 2>&1 \
36 // RUN:   | FileCheck %s --check-prefix=CHECK-nnNULL
37
38 // REQUIRES: stable-runtime
39
40 // TODO(alekseyshl): Fix it.
41 // UNSUPPORTED: android
42
43 #include <assert.h>
44 #include <errno.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <limits>
49 #include <new>
50
51 int main(int argc, char **argv) {
52   assert(argc == 2);
53   const char *action = argv[1];
54   fprintf(stderr, "%s:\n", action);
55
56   static const size_t kMaxAllowedMallocSizePlusOne = (2UL << 30) + 1;
57
58   void *x = nullptr;
59   if (!strcmp(action, "malloc")) {
60     x = malloc(kMaxAllowedMallocSizePlusOne);
61   } else if (!strcmp(action, "calloc")) {
62     x = calloc((kMaxAllowedMallocSizePlusOne / 4) + 1, 4);
63   } else if (!strcmp(action, "calloc-overflow")) {
64     volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max();
65     size_t kArraySize = 4096;
66     volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
67     x = calloc(kArraySize, kArraySize2);
68   } else if (!strcmp(action, "realloc")) {
69     x = realloc(0, kMaxAllowedMallocSizePlusOne);
70   } else if (!strcmp(action, "realloc-after-malloc")) {
71     char *t = (char*)malloc(100);
72     *t = 42;
73     x = realloc(t, kMaxAllowedMallocSizePlusOne);
74     assert(*t == 42);
75     free(t);
76   } else if (!strcmp(action, "new")) {
77     x = operator new(kMaxAllowedMallocSizePlusOne);
78   } else if (!strcmp(action, "new-nothrow")) {
79     x = operator new(kMaxAllowedMallocSizePlusOne, std::nothrow);
80   } else {
81     assert(0);
82   }
83
84   fprintf(stderr, "errno: %d\n", errno);
85
86   free(x);
87
88   return x != nullptr;
89 }
90
91 // CHECK-mCRASH: malloc:
92 // CHECK-mCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
93 // CHECK-cCRASH: calloc:
94 // CHECK-cCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
95 // CHECK-coCRASH: calloc-overflow:
96 // CHECK-coCRASH: SUMMARY: HWAddressSanitizer: calloc-overflow
97 // CHECK-rCRASH: realloc:
98 // CHECK-rCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
99 // CHECK-mrCRASH: realloc-after-malloc:
100 // CHECK-mrCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
101 // CHECK-nCRASH: new:
102 // CHECK-nCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
103 // CHECK-nCRASH-OOM: new:
104 // CHECK-nCRASH-OOM: SUMMARY: HWAddressSanitizer: out-of-memory
105 // CHECK-nnCRASH: new-nothrow:
106 // CHECK-nnCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
107
108 // CHECK-mNULL: malloc:
109 // CHECK-mNULL: errno: 12
110 // CHECK-cNULL: calloc:
111 // CHECK-cNULL: errno: 12
112 // CHECK-coNULL: calloc-overflow:
113 // CHECK-coNULL: errno: 12
114 // CHECK-rNULL: realloc:
115 // CHECK-rNULL: errno: 12
116 // CHECK-mrNULL: realloc-after-malloc:
117 // CHECK-mrNULL: errno: 12
118 // CHECK-nnNULL: new-nothrow: