diff options
author | Alex Shlyapnikov <alekseys@google.com> | 2018-06-11 19:45:59 +0000 |
---|---|---|
committer | Alex Shlyapnikov <alekseys@google.com> | 2018-06-11 19:45:59 +0000 |
commit | dfa62fd314bada8a38e6578ded49ae8679b3108e (patch) | |
tree | 14da3b9d04eed6dc02063fe11cb2df09888b6da9 /test/sanitizer_common | |
parent | f2f5d0836a38981d7ca46ac145467880aae82e2d (diff) |
[Sanitizers] Move allocator_returns_null.cc test to common.
Summary:
Add allocator_returns_null.cc test to sanitizer_common and
remove all sanitizer-specific ones except:
- HWASan is not covered by sanitizer_common
- TSan allocator does not have comprehensive error reporting yet
Reviewers: vitalybuka
Subscribers: kubamracek, delcypher, #sanitizers, llvm-commits
Differential Revision: https://reviews.llvm.org/D47971
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@334433 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/sanitizer_common')
-rw-r--r-- | test/sanitizer_common/TestCases/allocator_returns_null.cc | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/test/sanitizer_common/TestCases/allocator_returns_null.cc b/test/sanitizer_common/TestCases/allocator_returns_null.cc new file mode 100644 index 000000000..9d696156f --- /dev/null +++ b/test/sanitizer_common/TestCases/allocator_returns_null.cc @@ -0,0 +1,118 @@ +// Test the behavior of malloc/calloc/realloc/new when the allocation size +// exceeds the sanitizer's allocator max allowed one. +// By default (allocator_may_return_null=0) the process should crash. With +// allocator_may_return_null=1 the allocator should return 0 and set errno to +// the appropriate error code. +// +// RUN: %clangxx -O0 %s -o %t +// RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH +// RUN: %tool_options=allocator_may_return_null=0 not %run %t malloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-mCRASH +// RUN: %tool_options=allocator_may_return_null=1 %run %t malloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NULL +// RUN: %tool_options=allocator_may_return_null=0 not %run %t calloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-cCRASH +// RUN: %tool_options=allocator_may_return_null=1 %run %t calloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NULL +// RUN: %tool_options=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-coCRASH +// RUN: %tool_options=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NULL +// RUN: %tool_options=allocator_may_return_null=0 not %run %t realloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-rCRASH +// RUN: %tool_options=allocator_may_return_null=1 %run %t realloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NULL +// RUN: %tool_options=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-mrCRASH +// RUN: %tool_options=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NULL +// RUN: %tool_options=allocator_may_return_null=0 not %run %t new 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH +// RUN: %tool_options=allocator_may_return_null=1 not %run %t new 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH-OOM +// RUN: %tool_options=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-nnCRASH +// RUN: %tool_options=allocator_may_return_null=1 %run %t new-nothrow 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NULL + +// TODO(alekseyshl): win32 is disabled due to failing errno tests, fix it there. +// UNSUPPORTED: tsan, ubsan, win32 + +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <limits> +#include <new> + +int main(int argc, char **argv) { + assert(argc == 2); + const char *action = argv[1]; + fprintf(stderr, "%s:\n", action); + + // The maximum value of all supported sanitizers: + // ASan: asan_allocator.cc, search for kMaxAllowedMallocSize. + // LSan: lsan_allocator.cc, search for kMaxAllowedMallocSize. + // ASan + LSan: ASan limit is used. + // MSan: msan_allocator.cc, search for kMaxAllowedMallocSize. + // TSan: tsan_mman.cc, user_alloc_internal function. + static const size_t kMaxAllowedMallocSizePlusOne = +#if __LP64__ || defined(_WIN64) + (1ULL << 40) + 1; +#else + (3UL << 30) + 1; +#endif + + void *x = nullptr; + if (!strcmp(action, "malloc")) { + x = malloc(kMaxAllowedMallocSizePlusOne); + } else if (!strcmp(action, "calloc")) { + x = calloc((kMaxAllowedMallocSizePlusOne / 4) + 1, 4); + } else if (!strcmp(action, "calloc-overflow")) { + volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max(); + size_t kArraySize = 4096; + volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10; + x = calloc(kArraySize, kArraySize2); + } else if (!strcmp(action, "realloc")) { + x = realloc(0, kMaxAllowedMallocSizePlusOne); + } else if (!strcmp(action, "realloc-after-malloc")) { + char *t = (char*)malloc(100); + *t = 42; + x = realloc(t, kMaxAllowedMallocSizePlusOne); + assert(*t == 42); + free(t); + } else if (!strcmp(action, "new")) { + x = operator new(kMaxAllowedMallocSizePlusOne); + } else if (!strcmp(action, "new-nothrow")) { + x = operator new(kMaxAllowedMallocSizePlusOne, std::nothrow); + } else { + assert(0); + } + + fprintf(stderr, "errno: %d\n", errno); + + free(x); + + return x != nullptr; +} + +// CHECK-mCRASH: malloc: +// CHECK-mCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} +// CHECK-cCRASH: calloc: +// CHECK-cCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} +// CHECK-coCRASH: calloc-overflow: +// CHECK-coCRASH: {{SUMMARY: .*Sanitizer: calloc-overflow}} +// CHECK-rCRASH: realloc: +// CHECK-rCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} +// CHECK-mrCRASH: realloc-after-malloc: +// CHECK-mrCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} +// CHECK-nCRASH: new: +// CHECK-nCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} +// CHECK-nCRASH-OOM: new: +// CHECK-nCRASH-OOM: {{SUMMARY: .*Sanitizer: out-of-memory}} +// CHECK-nnCRASH: new-nothrow: +// CHECK-nnCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} + +// CHECK-NULL: {{malloc|calloc|calloc-overflow|realloc|realloc-after-malloc|new-nothrow}} +// CHECK-NULL: errno: 12 |