1 // RUN: %clang_dfsan -mllvm -dfsan-combine-pointer-labels-on-load=false %s -o %t && %run %t
2 // RUN: %clang_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -mllvm -dfsan-combine-pointer-labels-on-load=false %s -o %t && %run %t
3 //
4 // Tests custom implementations of various glibc functions.
5 //
6 // REQUIRES: x86_64-target-arch
7
8 #include <sanitizer/dfsan_interface.h>
9
10 #include <assert.h>
11 #include <malloc.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <sys/mman.h>
15
16 #define ASSERT_ZERO_LABEL(data) \
17 assert(0 == dfsan_get_label((long) (data)))
18
19 #define ASSERT_READ_ZERO_LABEL(ptr, size) \
20 assert(0 == dfsan_read_label(ptr, size))
21
22 const int kAlignment = 8;
23 const int kSize = 16;
24
test_aligned_alloc()25 void test_aligned_alloc() {
26 char *p = (char *) aligned_alloc(kAlignment, kSize);
27 ASSERT_ZERO_LABEL(p);
28 ASSERT_READ_ZERO_LABEL(p, kSize);
29 free(p);
30 }
31
test_calloc()32 void test_calloc() {
33 char *p = (char *) calloc(kSize, 1);
34 ASSERT_ZERO_LABEL(p);
35 ASSERT_READ_ZERO_LABEL(p, kSize);
36 free(p);
37 }
38
test_cfree()39 void test_cfree() {
40 // The current glibc does not support cfree.
41 }
42
test_free()43 void test_free() {
44 char *p = (char *) malloc(kSize);
45 dfsan_set_label(1, p, kSize);
46 free(p);
47 ASSERT_READ_ZERO_LABEL(p, kSize);
48 }
49
test_mallinfo()50 void test_mallinfo() {
51 struct mallinfo mi = mallinfo();
52 for (int i = 0; i < sizeof(struct mallinfo); ++i) {
53 char c = ((char *)(&mi))[i];
54 assert(!c);
55 ASSERT_ZERO_LABEL(c);
56 }
57 }
58
test_malloc()59 void test_malloc() {
60 char *p = (char *) malloc(kSize);
61 ASSERT_ZERO_LABEL(p);
62 ASSERT_READ_ZERO_LABEL(p, kSize);
63 free(p);
64 }
65
test_malloc_stats()66 void test_malloc_stats() {
67 // Only ensures it does not crash. Our interceptor of malloc_stats is empty.
68 malloc_stats();
69 }
70
test_malloc_usable_size()71 void test_malloc_usable_size() {
72 char *p = (char *) malloc(kSize);
73 size_t s = malloc_usable_size(p);
74 assert(s == kSize);
75 ASSERT_ZERO_LABEL(s);
76 free(p);
77 }
78
test_mallopt()79 void test_mallopt() {
80 int r = mallopt(0, 0);
81 assert(!r);
82 ASSERT_ZERO_LABEL(r);
83 }
84
test_memalign()85 void test_memalign() {
86 char *p = (char *) memalign(kAlignment, kSize);
87 ASSERT_ZERO_LABEL(p);
88 ASSERT_READ_ZERO_LABEL(p, kSize);
89 free(p);
90 }
91
test_mmap()92 void test_mmap() {
93 char *p = mmap(NULL, kSize, PROT_READ | PROT_WRITE,
94 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
95 ASSERT_READ_ZERO_LABEL(p, kSize);
96 char val = 0xff;
97 dfsan_set_label(1, &val, sizeof(val));
98 memset(p, val, kSize);
99 p = mmap(p, kSize, PROT_READ | PROT_WRITE,
100 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
101 ASSERT_READ_ZERO_LABEL(p, kSize);
102 munmap(p, kSize);
103 }
104
test_mmap64()105 void test_mmap64() {
106 // The current glibc does not support mmap64.
107 }
108
test_unmmap()109 void test_unmmap() {
110 char *p = mmap(NULL, kSize, PROT_READ | PROT_WRITE,
111 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
112 char val = 0xff;
113 dfsan_set_label(1, &val, sizeof(val));
114 memset(p, val, kSize);
115 munmap(p, kSize);
116 ASSERT_READ_ZERO_LABEL(p, kSize);
117 }
118
test_posix_memalign()119 void test_posix_memalign() {
120 char *p;
121 dfsan_set_label(1, &p, sizeof(p));
122 int r = posix_memalign((void **)&p, kAlignment, kSize);
123 assert(!r);
124 ASSERT_ZERO_LABEL(p);
125 ASSERT_READ_ZERO_LABEL(p, kSize);
126 free(p);
127 }
128
test_pvalloc()129 void test_pvalloc() {
130 char *p = (char *) pvalloc(kSize);
131 ASSERT_ZERO_LABEL(p);
132 ASSERT_READ_ZERO_LABEL(p, kSize);
133 free(p);
134 }
135
test_realloc()136 void test_realloc() {
137 char *p = (char *) malloc(kSize);
138
139 char *q = (char *) realloc(p, kSize * 2);
140 ASSERT_ZERO_LABEL(q);
141 ASSERT_READ_ZERO_LABEL(q, kSize * 2);
142
143 char *x = (char *) realloc(q, kSize);
144 ASSERT_ZERO_LABEL(x);
145 ASSERT_READ_ZERO_LABEL(x, kSize);
146
147 free(x);
148 }
149
test_reallocarray()150 void test_reallocarray() {
151 // The current glibc does not support reallocarray.
152 }
153
test_valloc()154 void test_valloc() {
155 char *p = (char *) valloc(kSize);
156 ASSERT_ZERO_LABEL(p);
157 ASSERT_READ_ZERO_LABEL(p, kSize);
158 free(p);
159 }
160
test___libc_memalign()161 void test___libc_memalign() {
162 // The current glibc does not support __libc_memalign.
163 }
164
test___tls_get_addr()165 void test___tls_get_addr() {
166 // The current glibc does not support __tls_get_addr.
167 }
168
main(void)169 int main(void) {
170 // With any luck this sequence of calls will cause allocators to return the
171 // same pointer. This is probably the best we can do to test these functions.
172 test_aligned_alloc();
173 test_calloc();
174 test_cfree();
175 test_free();
176 test_mallinfo();
177 test_malloc();
178 test_malloc_stats();
179 test_malloc_usable_size();
180 test_mallopt();
181 test_memalign();
182 test_mmap();
183 test_mmap64();
184 test_unmmap();
185 test_posix_memalign();
186 test_pvalloc();
187 test_realloc();
188 test_reallocarray();
189 test_valloc();
190 test___libc_memalign();
191 test___tls_get_addr();
192 }
193