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
16size_t round_up_to(size_t size, size_t alignment) {
17 return (size + alignment - 1) & ~(alignment - 1);
18}
19
20int 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