1 // RUN: %clang_scudo %s -o %t
2 // RUN:                                                 %run %t valid   2>&1
3 // RUN:                                             not %run %t invalid 2>&1 | FileCheck %s
4 // RUN: %env_scudo_opts=allocator_may_return_null=1     %run %t invalid 2>&1
5 // UNSUPPORTED: android
6 
7 // Tests that valloc and pvalloc work as intended.
8 
9 #include <assert.h>
10 #include <errno.h>
11 #include <malloc.h>
12 #include <stdint.h>
13 #include <string.h>
14 #include <unistd.h>
15 
round_up_to(size_t size,size_t alignment)16 size_t round_up_to(size_t size, size_t alignment) {
17   return (size + alignment - 1) & ~(alignment - 1);
18 }
19 
main(int argc,char ** argv)20 int main(int argc, char **argv)
21 {
22   void *p = NULL;
23   size_t size, page_size;
24 
25   assert(argc == 2);
26 
27   page_size = sysconf(_SC_PAGESIZE);
28   // Check that the page size is a power of two.
29   assert((page_size & (page_size - 1)) == 0);
30 
31   if (!strcmp(argv[1], "valid")) {
32     for (int i = (sizeof(void *) == 4) ? 3 : 4; i < 21; i++) {
33       size = 1U << i;
34       p = valloc(size - (2 * sizeof(void *)));
35       assert(p);
36       assert(((uintptr_t)p & (page_size - 1)) == 0);
37       free(p);
38       p = pvalloc(size - (2 * sizeof(void *)));
39       assert(p);
40       assert(((uintptr_t)p & (page_size - 1)) == 0);
41       assert(malloc_usable_size(p) >= round_up_to(size, page_size));
42       free(p);
43       p = valloc(size);
44       assert(p);
45       assert(((uintptr_t)p & (page_size - 1)) == 0);
46       free(p);
47       p = pvalloc(size);
48       assert(p);
49       assert(((uintptr_t)p & (page_size - 1)) == 0);
50       assert(malloc_usable_size(p) >= round_up_to(size, page_size));
51       free(p);
52     }
53   }
54   if (!strcmp(argv[1], "invalid")) {
55     // Size passed to pvalloc overflows when rounded up.
56     p = pvalloc((size_t)-1);
57     // CHECK: Scudo ERROR: pvalloc parameters overflow
58     assert(!p);
59     assert(errno == ENOMEM);
60     errno = 0;
61     p = pvalloc((size_t)-page_size);
62     assert(!p);
63     assert(errno == ENOMEM);
64   }
65   return 0;
66 }
67