1 //===----------- dlclose-test.cc --------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of AddressSanitizer, an address sanity checker.
11 //
12 // Regression test for
13 // http://code.google.com/p/address-sanitizer/issues/detail?id=19
14 // Bug description:
15 // 1. application dlopens foo.so
16 // 2. asan registers all globals from foo.so
17 // 3. application dlcloses foo.so
18 // 4. application mmaps some memory to the location where foo.so was before
19 // 5. application starts using this mmaped memory, but asan still thinks there
20 // are globals.
21 // 6. BOOM
22 //===----------------------------------------------------------------------===//
23 #include <assert.h>
24 #include <dlfcn.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <sys/mman.h>
28
29 #include <string>
30
31 using std::string;
32
33 static const int kPageSize = 4096;
34
35 typedef int *(fun_t)();
36
main(int argc,char * argv[])37 int main(int argc, char *argv[]) {
38 string path = string(argv[0]) + "-so.so";
39 printf("opening %s ... \n", path.c_str());
40 void *lib = dlopen(path.c_str(), RTLD_NOW);
41 if (!lib) {
42 printf("error in dlopen(): %s\n", dlerror());
43 return 1;
44 }
45 fun_t *get = (fun_t*)dlsym(lib, "get_address_of_static_var");
46 if (!get) {
47 printf("failed dlsym\n");
48 return 1;
49 }
50 int *addr = get();
51 assert(((size_t)addr % 32) == 0); // should be 32-byte aligned.
52 printf("addr: %p\n", addr);
53 addr[0] = 1; // make sure we can write there.
54
55 // Now dlclose the shared library.
56 printf("attempting to dlclose\n");
57 if (dlclose(lib)) {
58 printf("failed to dlclose\n");
59 return 1;
60 }
61 // Now, the page where 'addr' is unmapped. Map it.
62 size_t page_beg = ((size_t)addr) & ~(kPageSize - 1);
63 void *res = mmap((void*)(page_beg), kPageSize,
64 PROT_READ | PROT_WRITE,
65 MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 0, 0);
66 if (res == (char*)-1L) {
67 printf("failed to mmap\n");
68 return 1;
69 }
70 addr[1] = 2; // BOOM (if the bug is not fixed).
71 printf("PASS\n");
72 // Check-Common: PASS
73 return 0;
74 }
75