1 // RUN: %clangxx_scudo %s -lstdc++ -o %t 2 // RUN: %run %t ownership 2>&1 3 // RUN: %run %t ownership-and-size 2>&1 4 // RUN: %run %t heap-size 2>&1 5 // RUN: %env_scudo_opts="allocator_may_return_null=1" %run %t soft-limit 2>&1 6 // RUN: %env_scudo_opts="allocator_may_return_null=1" not %run %t hard-limit 2>&1 7 8 // Tests that the sanitizer interface functions behave appropriately. 9 10 #include <stdlib.h> 11 #include <assert.h> 12 #include <string.h> 13 #include <unistd.h> 14 15 #include <vector> 16 17 #include <sanitizer/allocator_interface.h> 18 #include <sanitizer/scudo_interface.h> 19 20 int main(int argc, char **argv) 21 { 22 assert(argc == 2); 23 24 if (!strcmp(argv[1], "ownership")) { 25 // Ensures that __sanitizer_get_ownership can be called before any other 26 // allocator function, and that it behaves properly on a pointer not owned 27 // by us. 28 assert(!__sanitizer_get_ownership(argv)); 29 } 30 if (!strcmp(argv[1], "ownership-and-size")) { 31 // Tests that __sanitizer_get_ownership and __sanitizer_get_allocated_size 32 // behave properly on chunks allocated by the Primary and Secondary. 33 void *p; 34 std::vector<ssize_t> sizes{1, 8, 16, 32, 1024, 32768, 35 1 << 16, 1 << 17, 1 << 20, 1 << 24}; 36 for (size_t size : sizes) { 37 p = malloc(size); 38 assert(p); 39 assert(__sanitizer_get_ownership(p)); 40 assert(__sanitizer_get_allocated_size(p) >= size); 41 free(p); 42 } 43 } 44 if (!strcmp(argv[1], "heap-size")) { 45 // Ensures that __sanitizer_get_heap_size can be called before any other 46 // allocator function. 47 assert(__sanitizer_get_heap_size() >= 0); 48 } 49 if (!strcmp(argv[1], "soft-limit")) { 50 // Verifies that setting the soft RSS limit at runtime works as expected. 51 std::vector<void *> pointers; 52 size_t size = 1 << 19; // 512Kb 53 for (int i = 0; i < 5; i++) { 54 void *p = malloc(size); 55 memset(p, 0, size); 56 pointers.push_back(p); 57 } 58 // Set the soft RSS limit to 1Mb. 59 __scudo_set_rss_limit(1, 0); 60 usleep(20000); 61 // The following allocation should return NULL. 62 void *p = malloc(size); 63 assert(!p); 64 // Remove the soft RSS limit. 65 __scudo_set_rss_limit(0, 0); 66 // The following allocation should succeed. 67 p = malloc(size); 68 assert(p); 69 free(p); 70 while (!pointers.empty()) { 71 free(pointers.back()); 72 pointers.pop_back(); 73 } 74 } 75 if (!strcmp(argv[1], "hard-limit")) { 76 // Verifies that setting the hard RSS limit at runtime works as expected. 77 std::vector<void *> pointers; 78 size_t size = 1 << 19; // 512Kb 79 for (int i = 0; i < 5; i++) { 80 void *p = malloc(size); 81 memset(p, 0, size); 82 pointers.push_back(p); 83 } 84 // Set the hard RSS limit to 1Mb 85 __scudo_set_rss_limit(1, 1); 86 usleep(20000); 87 // The following should trigger our death. 88 void *p = malloc(size); 89 } 90 91 return 0; 92 } 93