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.