1 // Test that globals from different shared objects all get registered. 2 3 // This source file is compiled into three different source object files. Each 4 // object file declares a global buffer. The first two are linked together, and 5 // the third is loaded at runtime. We make sure that out-of-bounds accesses 6 // are caught for all three buffers. 7 8 // RUN: %clang_asan -c -o %t-one.o -DMAIN_FILE %s 9 // RUN: %clang_asan -c -o %t-two.o -DSECONDARY_FILE %s 10 // RUN: %clang_asan -o %t %t-one.o %t-two.o %libdl 11 // RUN: %clang_asan -o %t-dynamic.so -shared -fPIC -DSHARED_LIBRARY_FILE %s 12 // RUN: not %run %t 1 2>&1 | FileCheck --check-prefix ASAN-CHECK-1 %s 13 // RUN: not %run %t 2 2>&1 | FileCheck --check-prefix ASAN-CHECK-2 %s 14 // RUN: not %run %t 3 2>&1 | FileCheck --check-prefix ASAN-CHECK-3 %s 15 16 #if MAIN_FILE 17 18 #include <dlfcn.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 23 extern char buffer1[1]; 24 extern char buffer2[1]; 25 char buffer1[1] = { 0 }; 26 27 int main(int argc, char *argv[]) { 28 int n = atoi(argv[1]); 29 if (n == 1) { 30 buffer1[argc] = 0; 31 // ASAN-CHECK-1: {{0x.* is located 1 bytes .* 'buffer1'}} 32 } else if (n == 2) { 33 buffer2[argc] = 0; 34 // ASAN-CHECK-2: {{0x.* is located 1 bytes .* 'buffer2'}} 35 } else if (n == 3) { 36 char *libsuffix = "-dynamic.so"; 37 char *libpath = malloc(strlen(argv[0]) + strlen(libsuffix) + 1); 38 sprintf(libpath, "%s%s", argv[0], libsuffix); 39 40 void *handle = dlopen(libpath, RTLD_NOW); 41 if (!handle) { 42 fprintf(stderr, "dlopen: %s\n", dlerror()); 43 return 1; 44 } 45 46 char *buffer = (char *)dlsym(handle, "buffer3"); 47 if (!buffer) { 48 fprintf(stderr, "dlsym: %s\n", dlerror()); 49 return 1; 50 } 51 52 buffer[argc] = 0; 53 // ASAN-CHECK-3: {{0x.* is located 1 bytes .* 'buffer3'}} 54 } 55 56 return 0; 57 } 58 59 #elif SECONDARY_FILE 60 61 extern char buffer2[1]; 62 char buffer2[1] = { 0 }; 63 64 #elif SHARED_LIBRARY_FILE 65 66 extern char buffer3[1]; 67 char buffer3[1] = { 0 }; 68 69 #endif 70