1673dc3d4SNico Weber // Test the behavior of malloc/calloc/realloc when the allocation causes OOM 2673dc3d4SNico Weber // in the secondary allocator. 3673dc3d4SNico Weber // By default (allocator_may_return_null=0) the process should crash. 4673dc3d4SNico Weber // With allocator_may_return_null=1 the allocator should return 0. 5673dc3d4SNico Weber // Set the limit to 20.5T on 64 bits to account for ASan shadow memory, 6673dc3d4SNico Weber // allocator buffers etc. so that the test allocation of ~1T will trigger OOM. 7673dc3d4SNico Weber // Limit this test to Linux since we're relying on allocator internal 8673dc3d4SNico Weber // limits (shadow memory size, allocation limits etc.) 9673dc3d4SNico Weber 10673dc3d4SNico Weber // RUN: %clangxx_asan -O0 %s -o %t 11673dc3d4SNico Weber // RUN: ulimit -v 22024290304 12673dc3d4SNico Weber // RUN: not %run %t malloc 2>&1 \ 13673dc3d4SNico Weber // RUN: | FileCheck %s --check-prefixes=CHECK-MALLOC,CHECK-CRASH 14673dc3d4SNico Weber // RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 \ 15673dc3d4SNico Weber // RUN: | FileCheck %s --check-prefixes=CHECK-MALLOC,CHECK-CRASH 16673dc3d4SNico Weber // RUN: %env_asan_opts=allocator_may_return_null=1 %run %t malloc 2>&1 \ 17673dc3d4SNico Weber // RUN: | FileCheck %s --check-prefixes=CHECK-MALLOC,CHECK-NULL 18673dc3d4SNico Weber // RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 \ 19673dc3d4SNico Weber // RUN: | FileCheck %s --check-prefixes=CHECK-CALLOC,CHECK-CRASH 20673dc3d4SNico Weber // RUN: %env_asan_opts=allocator_may_return_null=1 %run %t calloc 2>&1 \ 21673dc3d4SNico Weber // RUN: | FileCheck %s --check-prefixes=CHECK-CALLOC,CHECK-NULL 22673dc3d4SNico Weber // RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 \ 23673dc3d4SNico Weber // RUN: | FileCheck %s --check-prefixes=CHECK-REALLOC,CHECK-CRASH 24673dc3d4SNico Weber // RUN: %env_asan_opts=allocator_may_return_null=1 %run %t realloc 2>&1 \ 25673dc3d4SNico Weber // RUN: | FileCheck %s --check-prefixes=CHECK-REALLOC,CHECK-NULL 26673dc3d4SNico Weber // RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \ 27673dc3d4SNico Weber // RUN: | FileCheck %s --check-prefixes=CHECK-MALLOC-REALLOC,CHECK-CRASH 28673dc3d4SNico Weber // RUN: %env_asan_opts=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 \ 29673dc3d4SNico Weber // RUN: | FileCheck %s --check-prefixes=CHECK-MALLOC-REALLOC,CHECK-NULL 30673dc3d4SNico Weber 31673dc3d4SNico Weber // ASan shadow memory on s390 is too large for this test. 32673dc3d4SNico Weber // AArch64 bots fail on this test. 33673dc3d4SNico Weber // TODO(alekseys): Android lit do not run ulimit on device. 34*2d37e48eSHarini0924 // REQUIRES: shell, shadow-scale-3 35abd09754SPaul Robinson // UNSUPPORTED: android, target={{(s390|aarch64|powerpc64le).*}} 36673dc3d4SNico Weber 37673dc3d4SNico Weber #include <stdlib.h> 38673dc3d4SNico Weber #include <string.h> 39673dc3d4SNico Weber #include <stdio.h> 40673dc3d4SNico Weber #include <assert.h> 41673dc3d4SNico Weber 42673dc3d4SNico Weber int main(int argc, char **argv) { 43673dc3d4SNico Weber assert(argc == 2); 44673dc3d4SNico Weber const char *action = argv[1]; 45673dc3d4SNico Weber fprintf(stderr, "%s:\n", action); 46673dc3d4SNico Weber 47673dc3d4SNico Weber // Allocate just a bit less than max allocation size enforced by ASan's 48673dc3d4SNico Weber // allocator (currently 1T and 3G). 49673dc3d4SNico Weber const size_t size = 50673dc3d4SNico Weber #if __LP64__ 51673dc3d4SNico Weber (1ULL << 40) - (1ULL << 30); 52673dc3d4SNico Weber #else 53673dc3d4SNico Weber (3ULL << 30) - (1ULL << 20); 54673dc3d4SNico Weber #endif 55673dc3d4SNico Weber 56673dc3d4SNico Weber void *x = 0; 57673dc3d4SNico Weber 58673dc3d4SNico Weber if (!strcmp(action, "malloc")) { 59673dc3d4SNico Weber x = malloc(size); 60673dc3d4SNico Weber } else if (!strcmp(action, "calloc")) { 61673dc3d4SNico Weber x = calloc(size / 4, 4); 62673dc3d4SNico Weber } else if (!strcmp(action, "realloc")) { 63673dc3d4SNico Weber x = realloc(0, size); 64673dc3d4SNico Weber } else if (!strcmp(action, "realloc-after-malloc")) { 65673dc3d4SNico Weber char *t = (char*)malloc(100); 66673dc3d4SNico Weber *t = 42; 67673dc3d4SNico Weber x = realloc(t, size); 68673dc3d4SNico Weber assert(*t == 42); 69673dc3d4SNico Weber free(t); 70673dc3d4SNico Weber } else { 71673dc3d4SNico Weber assert(0); 72673dc3d4SNico Weber } 73673dc3d4SNico Weber 74673dc3d4SNico Weber // The NULL pointer is printed differently on different systems, while (long)0 75673dc3d4SNico Weber // is always the same. 76673dc3d4SNico Weber fprintf(stderr, "x: %lx\n", (long)x); 77673dc3d4SNico Weber free(x); 78673dc3d4SNico Weber 79673dc3d4SNico Weber return x != 0; 80673dc3d4SNico Weber } 81673dc3d4SNico Weber 82673dc3d4SNico Weber // CHECK-MALLOC: malloc: 83673dc3d4SNico Weber // CHECK-CALLOC: calloc: 84673dc3d4SNico Weber // CHECK-REALLOC: realloc: 85673dc3d4SNico Weber // CHECK-MALLOC-REALLOC: realloc-after-malloc: 86673dc3d4SNico Weber 87673dc3d4SNico Weber // CHECK-CRASH: SUMMARY: AddressSanitizer: out-of-memory 88673dc3d4SNico Weber // CHECK-NULL: x: 0 89