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
4 // Tests custom implementations of various glibc functions.
6 #include <sanitizer/dfsan_interface.h>
14 #define ASSERT_ZERO_LABEL(data) \
15 assert(0 == dfsan_get_label((long) (data)))
17 #define ASSERT_READ_ZERO_LABEL(ptr, size) \
18 assert(0 == dfsan_read_label(ptr, size))
20 const int kAlignment
= 8;
23 void test_aligned_alloc() {
24 char *p
= (char *) aligned_alloc(kAlignment
, kSize
);
26 ASSERT_READ_ZERO_LABEL(p
, kSize
);
31 char *p
= (char *) calloc(kSize
, 1);
33 ASSERT_READ_ZERO_LABEL(p
, kSize
);
38 // The current glibc does not support cfree.
42 char *p
= (char *) malloc(kSize
);
43 dfsan_set_label(1, p
, kSize
);
45 ASSERT_READ_ZERO_LABEL(p
, kSize
);
48 void test_mallinfo() {
49 // The mallinfo interceptor takes an argument instead of returning a struct.
50 // This doesn't work on AArch64 which uses different registers for the two
52 #if defined(__GLIBC__) && !defined(__aarch64__)
53 struct mallinfo mi
= mallinfo();
54 for (int i
= 0; i
< sizeof(struct mallinfo
); ++i
) {
55 char c
= ((char *)(&mi
))[i
];
63 char *p
= (char *) malloc(kSize
);
65 ASSERT_READ_ZERO_LABEL(p
, kSize
);
69 void test_malloc_stats() {
70 // Only ensures it does not crash. Our interceptor of malloc_stats is empty.
74 void test_malloc_usable_size() {
75 char *p
= (char *) malloc(kSize
);
76 size_t s
= malloc_usable_size(p
);
83 int r
= mallopt(0, 0);
88 void test_memalign() {
89 char *p
= (char *) memalign(kAlignment
, kSize
);
91 ASSERT_READ_ZERO_LABEL(p
, kSize
);
96 char *p
= mmap(NULL
, kSize
, PROT_READ
| PROT_WRITE
,
97 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
98 ASSERT_READ_ZERO_LABEL(p
, kSize
);
100 dfsan_set_label(1, &val
, sizeof(val
));
101 memset(p
, val
, kSize
);
102 p
= mmap(p
, kSize
, PROT_READ
| PROT_WRITE
,
103 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
104 ASSERT_READ_ZERO_LABEL(p
, kSize
);
109 // The current glibc does not support mmap64.
113 char *p
= mmap(NULL
, kSize
, PROT_READ
| PROT_WRITE
,
114 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
116 dfsan_set_label(1, &val
, sizeof(val
));
117 memset(p
, val
, kSize
);
119 ASSERT_READ_ZERO_LABEL(p
, kSize
);
122 void test_posix_memalign() {
124 dfsan_set_label(1, &p
, sizeof(p
));
125 int r
= posix_memalign((void **)&p
, kAlignment
, kSize
);
127 ASSERT_ZERO_LABEL(p
);
128 ASSERT_READ_ZERO_LABEL(p
, kSize
);
132 void test_pvalloc() {
133 char *p
= (char *) pvalloc(kSize
);
134 ASSERT_ZERO_LABEL(p
);
135 ASSERT_READ_ZERO_LABEL(p
, kSize
);
139 void test_realloc() {
140 char *p
= (char *) malloc(kSize
);
142 char *q
= (char *) realloc(p
, kSize
* 2);
143 ASSERT_ZERO_LABEL(q
);
144 ASSERT_READ_ZERO_LABEL(q
, kSize
* 2);
146 char *x
= (char *) realloc(q
, kSize
);
147 ASSERT_ZERO_LABEL(x
);
148 ASSERT_READ_ZERO_LABEL(x
, kSize
);
153 void test_reallocarray() {
154 // The current glibc does not support reallocarray.
158 char *p
= (char *) valloc(kSize
);
159 ASSERT_ZERO_LABEL(p
);
160 ASSERT_READ_ZERO_LABEL(p
, kSize
);
164 void test___libc_memalign() {
165 // The current glibc does not support __libc_memalign.
168 void test___tls_get_addr() {
169 // The current glibc does not support __tls_get_addr.
173 // With any luck this sequence of calls will cause allocators to return the
174 // same pointer. This is probably the best we can do to test these functions.
175 test_aligned_alloc();
182 test_malloc_usable_size();
188 test_posix_memalign();
193 test___libc_memalign();
194 test___tls_get_addr();