Comment #3 on issue 398 by [email protected]: Crash on ODR between instrumented and non-instrumented libraries
https://code.google.com/p/address-sanitizer/issues/detail?id=398

Hm, I've tried the following (draft) patch:

diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index f7b7a71..71b65c3 100644
--- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1338,8 +1338,14 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
       SourceLoc = ConstantInt::get(IntptrTy, 0);
     }

+    // Create local alias for NewGlobal to avoid crash on ODR between
+    // instrumented and non-instrumented libraries.
+    // https://code.google.com/p/address-sanitizer/issues/detail?id=398
+    auto *GA = GlobalAlias::create(
+        GlobalValue::InternalLinkage, MD.Name + M.getName(), NewGlobal);
+
     Initializers[i] = ConstantStruct::get(
-        GlobalStructTy, ConstantExpr::getPointerCast(NewGlobal, IntptrTy),
+        GlobalStructTy, ConstantExpr::getPointerCast(GA, IntptrTy),
         ConstantInt::get(IntptrTy, SizeInBytes),
         ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
         ConstantExpr::getPointerCast(Name, IntptrTy),

on this testcase:

$ cat main.c

int f = 4;
int g = 5;
int foo (int *);
int main ()
{
  return foo (&f) - 4;
}

$ cat libfoo.c

int f = 444;
int g = 555;
int foo (int *p)
{
  return *p;
}

and got interesting results. If we force clang to use external (GNU) AS via '-no-integrated-as' option, everything works well:

$ clang -no-integrated-as -fsanitize=address libfoo.c -shared -fpic -fsanitize=address -o libfoo.so
$ clang main.c -c -o main.o
$ clang -fsanitize=address main.o ./libfoo.so -o main
$ ASAN_OPTIONS=report_globals=3  ./main
#0 0x4b49b7 in __asan_register_globals /home/max/src/llvm/projects/compiler-rt/lib/asan/asan_globals.cc:226
    #1 0x7fb518d1fa0d in asan.module_ctor (libfoo.so+0xa0d)
#2 0x7fb518f31139 in call_init /build/buildd/eglibc-2.19/elf/dl-init.c:78 #3 0x7fb518f31222 in call_init /build/buildd/eglibc-2.19/elf/dl-init.c:36 #4 0x7fb518f31222 in _dl_init /build/buildd/eglibc-2.19/elf/dl-init.c:126
    #5 0x7fb518f22309  (/lib64/ld-linux-x86-64.so.2+0x1309)

=== ID 629145601; 0x7fb518f20100 0x7fb518f20138
==18620==Added Global[0x7fb518f20100]: beg=0x7fb518f20080 size=4/64 name=f module=foo.c dyn_init=0
==18620==  location (0x7fb518f1fdf8): name=foo.c[0x7fb518d1fa39], 1 5
==18620==Added Global[0x7fb518f20138]: beg=0x7fb518f200c0 size=4/64 name=g module=foo.c dyn_init=0
==18620==  location (0x7fb518f1fe08): name=foo.c[0x7fb518d1fa39], 2 5
==18620==Removed Global[0x7fb518f20100]: beg=0x7fb518f20080 size=4/64 name=f module=foo.c dyn_init=0
==18620==  location (0x7fb518f1fdf8): name=foo.c[0x7fb518d1fa39], 1 5
==18620==Removed Global[0x7fb518f20138]: beg=0x7fb518f200c0 size=4/64 name=g module=foo.c dyn_init=0
==18620==  location (0x7fb518f1fe08): name=foo.c[0x7fb518d1fa39], 2 5

For f and g, beg is located in libfoo.so and this is fine.

However, when use embedded clang asm, I've got this:

$ clang -fsanitize=address libfoo.c -shared -fpic -fsanitize=address -o libfoo.so
$ clang main.c -c -o main.o
$ clang -fsanitize=address main.o ./libfoo.so -o main

$ ASAN_OPTIONS=report_globals=3   ./main
#0 0x4b49b7 in __asan_register_globals /home/max/src/llvm/projects/compiler-rt/lib/asan/asan_globals.cc:226
    #1 0x7f09ab41da0d in asan.module_ctor (libfoo.so+0xa0d)
#2 0x7f09ab62f139 in call_init /build/buildd/eglibc-2.19/elf/dl-init.c:78 #3 0x7f09ab62f222 in call_init /build/buildd/eglibc-2.19/elf/dl-init.c:36 #4 0x7f09ab62f222 in _dl_init /build/buildd/eglibc-2.19/elf/dl-init.c:126
    #5 0x7f09ab620309  (/lib64/ld-linux-x86-64.so.2+0x1309)

=== ID 662700033; 0x7f09ab61e100 0x7f09ab61e138
==18635==Added Global[0x7f09ab61e100]: beg=0x00000070bb10 size=4/64 name=f module=foo.c dyn_init=0
==18635==  location (0x7f09ab61ddf8): name=foo.c[0x7f09ab41da39], 1 5
==18635==Added Global[0x7f09ab61e138]: beg=0x00000070bb14 size=4/64 name=g module=foo.c dyn_init=0
==18635==  location (0x7f09ab61de08): name=foo.c[0x7f09ab41da39], 2 5
==18635==AddressSanitizer CHECK failed: /home/max/src/llvm/projects/compiler-rt/lib/asan/asan_globals.cc:146 "((AddrIsAlignedByGranularity(g->beg))) != (0)" (0x0, 0x0) #0 0x4bca0d in __asan::AsanCheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) /home/max/src/llvm/projects/compiler-rt/lib/asan/asan_rtl.cc:71 #1 0x4c3b03 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) /home/max/src/llvm/projects/compiler-rt/lib/sanitizer_common/sanitizer_common.cc:136 #2 0x4b520b in RegisterGlobal /home/max/src/llvm/projects/compiler-rt/lib/asan/asan_globals.cc:146 #3 0x4b520b in __asan_register_globals /home/max/src/llvm/projects/compiler-rt/lib/asan/asan_globals.cc:230
    #4 0x7f09ab41da0d in asan.module_ctor (libfoo.so+0xa0d)
#5 0x7f09ab62f139 in call_init /build/buildd/eglibc-2.19/elf/dl-init.c:78 #6 0x7f09ab62f222 in call_init /build/buildd/eglibc-2.19/elf/dl-init.c:36 #7 0x7f09ab62f222 in _dl_init /build/buildd/eglibc-2.19/elf/dl-init.c:126
    #8 0x7f09ab620309  (/lib64/ld-linux-x86-64.so.2+0x1309)

Here, beg for f and g beg=0x00000070bb**, that is located in main. So, for embedded asm local aliases didn't work. I wonder if this is an assembler bug? Or maybe there is another way to create local alias that would work with both external an embedded as?


--
You received this message because this project is configured to send all issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings

--
You received this message because you are subscribed to the Google Groups 
"address-sanitizer" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to