[compiler-rt] r230288 - [ASan] Disable strict init-order checking if dlopen() is called.
Alexey Samsonov
vonosmas at gmail.com
Mon Feb 23 16:37:34 PST 2015
Author: samsonov
Date: Mon Feb 23 18:37:27 2015
New Revision: 230288
URL: http://llvm.org/viewvc/llvm-project?rev=230288&view=rev
Log:
[ASan] Disable strict init-order checking if dlopen() is called.
Revise the fix to https://code.google.com/p/address-sanitizer/issues/detail?id=178:
always disable strict init-order checking the first time dlopen() is
called: at this point shared library is allowed to access globals
defined in the main executable, as they are guaranteed to be
initialized. Revise the test cases:
* simplify init-order-dlopen.cc test case: make it Linux-specific
(there's no strict init-order checking on other platforms anyway),
and single-threaded.
* reinforce init-order-pthread-create.cc test case: make sure that
init-order checker would produce a false positive unless we
turn it off at the moment we call pthread_create().
Added:
compiler-rt/trunk/test/asan/TestCases/Linux/init-order-dlopen.cc
Removed:
compiler-rt/trunk/test/asan/TestCases/Posix/init-order-dlopen.cc
Modified:
compiler-rt/trunk/lib/asan/asan_interceptors.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
compiler-rt/trunk/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc
compiler-rt/trunk/test/asan/TestCases/init-order-pthread-create.cc
Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=230288&r1=230287&r2=230288&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Mon Feb 23 18:37:27 2015
@@ -171,6 +171,12 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free,
do { \
} while (false)
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
+// Strict init-order checking is dlopen-hostile:
+// https://code.google.com/p/address-sanitizer/issues/detail?id=178
+#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \
+ if (flags()->strict_init_order) { \
+ StopInitOrderChecking(); \
+ }
#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \
CoverageUpdateMapping()
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=230288&r1=230287&r2=230288&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Mon Feb 23 18:37:27 2015
@@ -22,6 +22,7 @@
// COMMON_INTERCEPTOR_FD_RELEASE
// COMMON_INTERCEPTOR_FD_ACCESS
// COMMON_INTERCEPTOR_SET_THREAD_NAME
+// COMMON_INTERCEPTOR_ON_DLOPEN
// COMMON_INTERCEPTOR_ON_EXIT
// COMMON_INTERCEPTOR_MUTEX_LOCK
// COMMON_INTERCEPTOR_MUTEX_UNLOCK
@@ -101,6 +102,10 @@
#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)
#endif
+#ifndef COMMON_INTERCEPTOR_ON_DLOPEN
+#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) {}
+#endif
+
struct FileMetadata {
// For open_memstream().
char **addr;
@@ -4688,6 +4693,7 @@ INTERCEPTOR(int, fclose, __sanitizer_FIL
INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
void *ctx;
COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
+ COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag);
void *res = REAL(dlopen)(filename, flag);
COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
return res;
Modified: compiler-rt/trunk/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc?rev=230288&r1=230287&r2=230288&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc Mon Feb 23 18:37:27 2015
@@ -1,2 +1,2 @@
-void *bar(void *input);
-void *glob2 = bar((void*)0x2345);
+void *bar(void *input, bool sleep_before_init);
+void *glob2 = bar((void*)0x2345, true);
Added: compiler-rt/trunk/test/asan/TestCases/Linux/init-order-dlopen.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/init-order-dlopen.cc?rev=230288&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/init-order-dlopen.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/init-order-dlopen.cc Mon Feb 23 18:37:27 2015
@@ -0,0 +1,43 @@
+// Regression test for
+// https://code.google.com/p/address-sanitizer/issues/detail?id=178
+
+// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
+// RUN: %clangxx_asan -O0 %s %libdl -Wl,--export-dynamic -o %t
+// RUN: env ASAN_OPTIONS=strict_init_order=true %run %t 2>&1
+
+#if defined(SHARED_LIB)
+#include <stdio.h>
+
+struct Bar {
+ Bar(int val) : val(val) { printf("Bar::Bar(%d)\n", val); }
+ int val;
+};
+
+int get_foo_val();
+Bar global_bar(get_foo_val());
+#else // SHARED LIB
+#include <dlfcn.h>
+#include <stdio.h>
+#include <string>
+struct Foo {
+ Foo() : val(42) { printf("Foo::Foo()\n"); }
+ int val;
+};
+
+Foo global_foo;
+
+int get_foo_val() {
+ return global_foo.val;
+}
+
+int main(int argc, char *argv[]) {
+ std::string path = std::string(argv[0]) + "-so.so";
+ void *handle = dlopen(path.c_str(), RTLD_NOW);
+ if (!handle) {
+ printf("error in dlopen(): %s\n", dlerror());
+ return 1;
+ }
+ printf("%d\n", get_foo_val());
+ return 0;
+}
+#endif // SHARED_LIB
Removed: compiler-rt/trunk/test/asan/TestCases/Posix/init-order-dlopen.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Posix/init-order-dlopen.cc?rev=230287&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Posix/init-order-dlopen.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/Posix/init-order-dlopen.cc (removed)
@@ -1,72 +0,0 @@
-// Regression test for
-// https://code.google.com/p/address-sanitizer/issues/detail?id=178
-
-// Assume we're on Darwin and try to pass -U to the linker. If this flag is
-// unsupported, don't use it.
-// RUN: %clangxx_asan -O0 -DSHARED_LIB %s \
-// RUN: -fPIC -shared -o %t-so.so -Wl,-U,_inc_global || \
-// RUN: %clangxx_asan -O0 -DSHARED_LIB %s \
-// RUN: -fPIC -shared -o %t-so.so
-// If the linker doesn't support --export-dynamic (which is ELF-specific),
-// try to link without that option.
-// FIXME: find a better solution.
-// RUN: %clangxx_asan -O0 %s -pthread %libdl -o %t -Wl,--export-dynamic || \
-// RUN: %clangxx_asan -O0 %s -pthread %libdl -o %t
-// RUN: ASAN_OPTIONS=strict_init_order=true %run %t 2>&1 | FileCheck %s
-#if !defined(SHARED_LIB)
-#include <dlfcn.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <string>
-
-using std::string;
-
-int foo() {
- return 42;
-}
-int global = foo();
-
-__attribute__((visibility("default")))
-extern "C"
-void inc_global() {
- global++;
-}
-
-void *global_poller(void *arg) {
- while (true) {
- if (global != 42)
- break;
- usleep(100);
- }
- return 0;
-}
-
-int main(int argc, char *argv[]) {
- pthread_t p;
- pthread_create(&p, 0, global_poller, 0);
- string path = string(argv[0]) + "-so.so";
- if (0 == dlopen(path.c_str(), RTLD_NOW)) {
- fprintf(stderr, "dlerror: %s\n", dlerror());
- return 1;
- }
- pthread_join(p, 0);
- printf("PASSED\n");
- // CHECK: PASSED
- return 0;
-}
-#else // SHARED_LIB
-#include <stdio.h>
-#include <unistd.h>
-
-extern "C" void inc_global();
-
-int slow_init() {
- sleep(1);
- inc_global();
- return 42;
-}
-
-int slowly_init_glob = slow_init();
-#endif // SHARED_LIB
Modified: compiler-rt/trunk/test/asan/TestCases/init-order-pthread-create.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/init-order-pthread-create.cc?rev=230288&r1=230287&r2=230288&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/init-order-pthread-create.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/init-order-pthread-create.cc Mon Feb 23 18:37:27 2015
@@ -6,25 +6,36 @@
#include <stdio.h>
#include <pthread.h>
+#include <unistd.h>
-void *run(void *arg) {
- return arg;
+void *bar(void *input, bool sleep_before_init) {
+ if (sleep_before_init)
+ usleep(500000);
+ return input;
}
-void *foo(void *input) {
- pthread_t t;
- pthread_create(&t, 0, run, input);
- void *res;
- pthread_join(t, &res);
- return res;
-}
+void *glob = bar((void*)0x1234, false);
+extern void *glob2;
-void *bar(void *input) {
- return input;
+void *poll(void *arg) {
+ void **glob = (void**)arg;
+ while (true) {
+ usleep(100000);
+ printf("glob is now: %p\n", *glob);
+ }
}
-void *glob = foo((void*)0x1234);
-extern void *glob2;
+struct GlobalPollerStarter {
+ GlobalPollerStarter() {
+ pthread_t p;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_create(&p, 0, poll, &glob);
+ pthread_attr_destroy(&attr);
+ printf("glob poller is started");
+ }
+} global_poller;
int main() {
printf("%p %p\n", glob, glob2);
More information about the llvm-commits
mailing list