From 85f6bace7a20b03d7a754d83a1b655b504eee0e3 Mon Sep 17 00:00:00 2001 From: Alex Shlyapnikov Date: Wed, 28 Mar 2018 18:22:40 +0000 Subject: [ASan] Report proper ASan error on allocator failures instead of CHECK(0)-ing Summary: Currently many allocator specific errors (OOM, for example) are reported as a text message and CHECK(0) termination, not stack, no details, not too helpful nor informative. To improve the situation, ASan detailed errors were defined and reported under the appropriate conditions. Issue: https://github.com/google/sanitizers/issues/887 Reviewers: eugenis Subscribers: kubamracek, delcypher, #sanitizers, llvm-commits Differential Revision: https://reviews.llvm.org/D44404 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@328722 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../TestCases/Linux/aligned_alloc-alignment.cc | 19 ++++++++++++++++ test/asan/TestCases/Linux/allocator_oom_test.cc | 2 +- test/asan/TestCases/Linux/pvalloc-overflow.cc | 5 ++++- .../TestCases/Posix/posix_memalign-alignment.cc | 20 +++++++++++++++++ test/asan/TestCases/Windows/oom.cc | 2 +- test/asan/TestCases/allocator_returns_null.cc | 18 ++++++++------- test/asan/TestCases/calloc-overflow.cc | 19 ++++++++++++++++ test/asan/TestCases/malloc-size-too-big.cc | 26 ++++++++++++++++++++++ 8 files changed, 100 insertions(+), 11 deletions(-) create mode 100644 test/asan/TestCases/Linux/aligned_alloc-alignment.cc create mode 100644 test/asan/TestCases/Posix/posix_memalign-alignment.cc create mode 100644 test/asan/TestCases/calloc-overflow.cc create mode 100644 test/asan/TestCases/malloc-size-too-big.cc (limited to 'test/asan') diff --git a/test/asan/TestCases/Linux/aligned_alloc-alignment.cc b/test/asan/TestCases/Linux/aligned_alloc-alignment.cc new file mode 100644 index 000000000..618aa8af7 --- /dev/null +++ b/test/asan/TestCases/Linux/aligned_alloc-alignment.cc @@ -0,0 +1,19 @@ +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s +// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL + +#include +#include + +int main() { + void *p = aligned_alloc(17, 100); + // CHECK: ERROR: AddressSanitizer: invalid allocation alignment: 17 + // CHECK: {{#0 0x.* in .*aligned_alloc}} + // CHECK: {{#1 0x.* in main .*aligned_alloc-alignment.cc:}}[[@LINE-3]] + // CHECK: SUMMARY: AddressSanitizer: invalid-allocation-alignment + + printf("pointer after failed aligned_alloc: %zd\n", (size_t)p); + // CHECK-NULL: pointer after failed aligned_alloc: 0 + + return 0; +} diff --git a/test/asan/TestCases/Linux/allocator_oom_test.cc b/test/asan/TestCases/Linux/allocator_oom_test.cc index 638200378..69ca07d6d 100644 --- a/test/asan/TestCases/Linux/allocator_oom_test.cc +++ b/test/asan/TestCases/Linux/allocator_oom_test.cc @@ -84,5 +84,5 @@ int main(int argc, char **argv) { // CHECK-REALLOC: realloc: // CHECK-MALLOC-REALLOC: realloc-after-malloc: -// CHECK-CRASH: AddressSanitizer's allocator is terminating the process +// CHECK-CRASH: SUMMARY: AddressSanitizer: out-of-memory // CHECK-NULL: x: 0 diff --git a/test/asan/TestCases/Linux/pvalloc-overflow.cc b/test/asan/TestCases/Linux/pvalloc-overflow.cc index b47c6266b..1d40811fc 100644 --- a/test/asan/TestCases/Linux/pvalloc-overflow.cc +++ b/test/asan/TestCases/Linux/pvalloc-overflow.cc @@ -38,4 +38,7 @@ int main(int argc, char *argv[]) { return 0; } -// CHECK: AddressSanitizer's allocator is terminating the process +// CHECK: {{ERROR: AddressSanitizer: pvalloc parameters overflow: size .* rounded up to system page size .* cannot be represented in type size_t}} +// CHECK: {{#0 0x.* in .*pvalloc}} +// CHECK: {{#1 0x.* in main .*pvalloc-overflow.cc:}} +// CHECK: SUMMARY: AddressSanitizer: pvalloc-overflow diff --git a/test/asan/TestCases/Posix/posix_memalign-alignment.cc b/test/asan/TestCases/Posix/posix_memalign-alignment.cc new file mode 100644 index 000000000..208772d9f --- /dev/null +++ b/test/asan/TestCases/Posix/posix_memalign-alignment.cc @@ -0,0 +1,20 @@ +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s +// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL + +#include +#include + +int main() { + void *p = reinterpret_cast(42); + int res = posix_memalign(&p, 17, 100); + // CHECK: ERROR: AddressSanitizer: invalid alignment requested in posix_memalign: 17 + // CHECK: {{#0 0x.* in .*posix_memalign}} + // CHECK: {{#1 0x.* in main .*posix_memalign-alignment.cc:}}[[@LINE-3]] + // CHECK: SUMMARY: AddressSanitizer: invalid-posix-memalign-alignment + + printf("pointer after failed posix_memalign: %zd\n", (size_t)p); + // CHECK-NULL: pointer after failed posix_memalign: 42 + + return 0; +} diff --git a/test/asan/TestCases/Windows/oom.cc b/test/asan/TestCases/Windows/oom.cc index 71a9c2a75..4d68c145e 100644 --- a/test/asan/TestCases/Windows/oom.cc +++ b/test/asan/TestCases/Windows/oom.cc @@ -8,5 +8,5 @@ int main() { while (true) { void *ptr = malloc(200 * 1024 * 1024); // 200MB } -// CHECK: allocator is terminating the process instead of returning 0 +// CHECK: SUMMARY: AddressSanitizer: out-of-memory } diff --git a/test/asan/TestCases/allocator_returns_null.cc b/test/asan/TestCases/allocator_returns_null.cc index 8ce002f04..7d4a96866 100644 --- a/test/asan/TestCases/allocator_returns_null.cc +++ b/test/asan/TestCases/allocator_returns_null.cc @@ -30,7 +30,7 @@ // RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t new 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-nCRASH // RUN: %env_asan_opts=allocator_may_return_null=1 not %run %t new 2>&1 \ -// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH +// RUN: | FileCheck %s --check-prefix=CHECK-nCRASH-OOM // RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-nnCRASH // RUN: %env_asan_opts=allocator_may_return_null=1 %run %t new-nothrow 2>&1 \ @@ -98,19 +98,21 @@ int main(int argc, char **argv) { } // CHECK-mCRASH: malloc: -// CHECK-mCRASH: AddressSanitizer's allocator is terminating the process +// CHECK-mCRASH: SUMMARY: AddressSanitizer: allocation-size-too-big // CHECK-cCRASH: calloc: -// CHECK-cCRASH: AddressSanitizer's allocator is terminating the process +// CHECK-cCRASH: SUMMARY: AddressSanitizer: allocation-size-too-big // CHECK-coCRASH: calloc-overflow: -// CHECK-coCRASH: AddressSanitizer's allocator is terminating the process +// CHECK-coCRASH: SUMMARY: AddressSanitizer: calloc-overflow // CHECK-rCRASH: realloc: -// CHECK-rCRASH: AddressSanitizer's allocator is terminating the process +// CHECK-rCRASH: SUMMARY: AddressSanitizer: allocation-size-too-big // CHECK-mrCRASH: realloc-after-malloc: -// CHECK-mrCRASH: AddressSanitizer's allocator is terminating the process +// CHECK-mrCRASH: SUMMARY: AddressSanitizer: allocation-size-too-big // CHECK-nCRASH: new: -// CHECK-nCRASH: AddressSanitizer's allocator is terminating the process +// CHECK-nCRASH: SUMMARY: AddressSanitizer: allocation-size-too-big +// CHECK-nCRASH-OOM: new: +// CHECK-nCRASH-OOM: SUMMARY: AddressSanitizer: out-of-memory // CHECK-nnCRASH: new-nothrow: -// CHECK-nnCRASH: AddressSanitizer's allocator is terminating the process +// CHECK-nnCRASH: SUMMARY: AddressSanitizer: allocation-size-too-big // CHECK-mNULL: malloc: // CHECK-mNULL: errno: 12 diff --git a/test/asan/TestCases/calloc-overflow.cc b/test/asan/TestCases/calloc-overflow.cc new file mode 100644 index 000000000..65278101c --- /dev/null +++ b/test/asan/TestCases/calloc-overflow.cc @@ -0,0 +1,19 @@ +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s +// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL + +#include +#include + +int main() { + void *p = calloc(-1, 1000); + // CHECK: {{ERROR: AddressSanitizer: calloc parameters overflow: count \* size \(.* \* 1000\) cannot be represented in type size_t}} + // CHECK: {{#0 0x.* in .*calloc}} + // CHECK: {{#1 0x.* in main .*calloc-overflow.cc:}}[[@LINE-3]] + // CHECK: SUMMARY: AddressSanitizer: calloc-overflow + + printf("calloc returned: %zu\n", (size_t)p); + // CHECK-NULL: calloc returned: 0 + + return 0; +} diff --git a/test/asan/TestCases/malloc-size-too-big.cc b/test/asan/TestCases/malloc-size-too-big.cc new file mode 100644 index 000000000..f48d8a7f8 --- /dev/null +++ b/test/asan/TestCases/malloc-size-too-big.cc @@ -0,0 +1,26 @@ +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s +// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL + +#include +#include + +static const size_t kMaxAllowedMallocSizePlusOne = +#if __LP64__ || defined(_WIN64) + (1ULL << 40) + 1; +#else + (3UL << 30) + 1; +#endif + +int main() { + void *p = malloc(kMaxAllowedMallocSizePlusOne); + // CHECK: {{ERROR: AddressSanitizer: requested allocation size .* \(.* after adjustments for alignment, red zones etc\.\) exceeds maximum supported size}} + // CHECK: {{#0 0x.* in .*malloc}} + // CHECK: {{#1 0x.* in main .*malloc-size-too-big.cc:}}[[@LINE-3]] + // CHECK: SUMMARY: AddressSanitizer: allocation-size-too-big + + printf("malloc returned: %zu\n", (size_t)p); + // CHECK-NULL: malloc returned: 0 + + return 0; +} -- cgit v1.2.3