• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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