summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-05-17 12:51:13 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-05-17 12:51:13 +0000
commitff6728f2f88a3939a79de70eaaf856b304b65f0b (patch)
tree61fe9231e799cb4deaf4a3684f3f08fa2991ed63
parent6e23ac606e4fefc69f8df54036614e8bf973e489 (diff)
downloadbcm5719-llvm-ff6728f2f88a3939a79de70eaaf856b304b65f0b.tar.gz
bcm5719-llvm-ff6728f2f88a3939a79de70eaaf856b304b65f0b.zip
[msan] Unpoison dlpi_name in dl_iterate_phdr interceptor.
llvm-svn: 182093
-rw-r--r--compiler-rt/lib/msan/msan_interceptors.cc11
-rw-r--r--compiler-rt/lib/msan/tests/msan_test.cc67
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc12
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h9
4 files changed, 69 insertions, 30 deletions
diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc
index fde1fb0e78f..fcda7875261 100644
--- a/compiler-rt/lib/msan/msan_interceptors.cc
+++ b/compiler-rt/lib/msan/msan_interceptors.cc
@@ -815,15 +815,20 @@ INTERCEPTOR(void *, dlopen, const char *filename, int flag) {
return (void *)map;
}
-typedef int (*dl_iterate_phdr_cb)(void *info, SIZE_T size, void *data);
+typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size,
+ void *data);
struct dl_iterate_phdr_data {
dl_iterate_phdr_cb callback;
void *data;
};
-static int msan_dl_iterate_phdr_cb(void *info, SIZE_T size, void *data) {
- if (info)
+static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
+ void *data) {
+ if (info) {
__msan_unpoison(info, size);
+ if (info->dlpi_name)
+ __msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1);
+ }
dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;
__msan_unpoison_param(3);
return cbdata->callback(info, size, cbdata->data);
diff --git a/compiler-rt/lib/msan/tests/msan_test.cc b/compiler-rt/lib/msan/tests/msan_test.cc
index e9361f37c85..1e34b4b0010 100644
--- a/compiler-rt/lib/msan/tests/msan_test.cc
+++ b/compiler-rt/lib/msan/tests/msan_test.cc
@@ -1475,6 +1475,32 @@ TEST(MemorySanitizer, getrusage) {
EXPECT_NOT_POISONED(usage.ru_nivcsw);
}
+#ifdef __GLIBC__
+extern "C" {
+ extern void *__libc_stack_end;
+}
+
+static char **GetArgv(void) {
+ uintptr_t *stack_end = (uintptr_t *)__libc_stack_end;
+ return (char**)(stack_end + 1);
+}
+
+#else // __GLIBC__
+# error "TODO: port this"
+#endif
+
+// Compute the path to our loadable DSO. We assume it's in the same
+// directory. Only use string routines that we intercept so far to do this.
+static int PathToLoadable(char *buf, size_t sz) {
+ char **argv = GetArgv();
+ const char *basename = "libmsan_loadable.x86_64.so";
+ char *last_slash = strrchr(argv[0], '/');
+ assert(last_slash);
+ int res = snprintf(buf, sz, "%.*s/%s", int(last_slash - argv[0]), argv[0],
+ basename);
+ return res < sz ? 0 : res;
+}
+
static void dladdr_testfn() {}
TEST(MemorySanitizer, dladdr) {
@@ -1503,37 +1529,27 @@ static int dl_phdr_callback(struct dl_phdr_info *info, size_t size, void *data)
}
TEST(MemorySanitizer, dl_iterate_phdr) {
+ char path[4096];
+ int res = PathToLoadable(path, sizeof(path));
+ assert(!res);
+
+ // Having at least one dlopen'ed library in the process makes this more
+ // entertaining.
+ void *lib = dlopen(path, RTLD_LAZY);
+ ASSERT_NE((void*)0, lib);
+
int count = 0;
int result = dl_iterate_phdr(dl_phdr_callback, &count);
assert(count > 0);
+
+ dlclose(lib);
}
-namespace {
-#ifdef __GLIBC__
-extern "C" {
- extern void *__libc_stack_end;
-}
-
-static char **GetArgv(void) {
- uintptr_t *stack_end = (uintptr_t *)__libc_stack_end;
- return (char**)(stack_end + 1);
-}
-
-#else // __GLIBC__
-# error "TODO: port this"
-#endif
TEST(MemorySanitizer, dlopen) {
- // Compute the path to our loadable DSO. We assume it's in the same
- // directory. Only use string routines that we intercept so far to do this.
- char **argv = GetArgv();
- const char *basename = "libmsan_loadable.x86_64.so";
- size_t path_max = strlen(argv[0]) + 1 + strlen(basename) + 1;
- char *path = new char[path_max];
- char *last_slash = strrchr(argv[0], '/');
- assert(last_slash);
- snprintf(path, path_max, "%.*s/%s", int(last_slash - argv[0]),
- argv[0], basename);
+ char path[4096];
+ int res = PathToLoadable(path, sizeof(path));
+ assert(!res);
// We need to clear shadow for globals when doing dlopen. In order to test
// this, we have to poison the shadow for the DSO before we load it. In
@@ -1554,8 +1570,6 @@ TEST(MemorySanitizer, dlopen) {
EXPECT_POISONED(*dso_global);
dlclose(lib);
}
-
- delete[] path;
}
// Regression test for a crash in dlopen() interceptor.
@@ -1564,7 +1578,6 @@ TEST(MemorySanitizer, dlopenFailed) {
void *lib = dlopen(path, RTLD_LAZY);
ASSERT_EQ(0, lib);
}
-} // namespace
TEST(MemorySanitizer, scanf) {
const char *input = "42 hello";
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
index 1beab897bd0..f9014db3088 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -38,6 +38,7 @@
#endif // !SANITIZER_ANDROID
#if SANITIZER_LINUX
+#include <link.h>
#include <sys/vfs.h>
#include <sys/epoll.h>
#endif // SANITIZER_LINUX
@@ -120,4 +121,15 @@ namespace __sanitizer {
COMPILER_CHECK(sizeof(__sanitizer_pthread_attr_t) >= sizeof(pthread_attr_t));
COMPILER_CHECK(sizeof(__sanitizer::struct_sigaction_max_sz) >=
sizeof(__sanitizer::struct_sigaction_sz));
+#if SANITIZER_LINUX
+COMPILER_CHECK(offsetof(struct __sanitizer_dl_phdr_info, dlpi_addr) ==
+ offsetof(struct dl_phdr_info, dlpi_addr));
+COMPILER_CHECK(offsetof(struct __sanitizer_dl_phdr_info, dlpi_name) ==
+ offsetof(struct dl_phdr_info, dlpi_name));
+COMPILER_CHECK(offsetof(struct __sanitizer_dl_phdr_info, dlpi_phdr) ==
+ offsetof(struct dl_phdr_info, dlpi_phdr));
+COMPILER_CHECK(offsetof(struct __sanitizer_dl_phdr_info, dlpi_phnum) ==
+ offsetof(struct dl_phdr_info, dlpi_phnum));
+#endif
+
#endif // SANITIZER_LINUX || SANITIZER_MAC
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index ae960f73484..c923ff3ae8c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -74,6 +74,15 @@ namespace __sanitizer {
extern uptr sig_dfl;
uptr __sanitizer_in_addr_sz(int af);
+
+#if SANITIZER_LINUX
+ struct __sanitizer_dl_phdr_info {
+ uptr dlpi_addr;
+ const char *dlpi_name;
+ const void *dlpi_phdr;
+ short dlpi_phnum;
+ };
+#endif
} // namespace __sanitizer
#endif
OpenPOWER on IntegriCloud