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