summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2019-09-30 17:49:48 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2019-09-30 17:49:48 +0000
commit0f6ecea9555533c4414cf6addd2ffed02c1938ec (patch)
treeb3cf0f719a54b3947fd72c859bafe02bc2b8607e
parent2b7e04031eae52b103c2dd20d4aaf6c4a9f7251e (diff)
downloadcompiler-rt-0f6ecea9555533c4414cf6addd2ffed02c1938ec.tar.gz
[msan] Intercept __getrlimit.
Summary: This interceptor is useful on its own, but the main purpose of this change is to intercept libpthread initialization on linux/glibc in order to run __msan_init before any .preinit_array constructors. We used to trigger on pthread_initialize_minimal -> getrlimit(), but that call has changed to __getrlimit at some point. Reviewers: vitalybuka, pcc Subscribers: jfb, #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D68168 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@373239 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/msan/msan_interceptors.cpp24
-rw-r--r--test/msan/preinit_array.cpp16
2 files changed, 33 insertions, 7 deletions
diff --git a/lib/msan/msan_interceptors.cpp b/lib/msan/msan_interceptors.cpp
index ff760e43d..1d9d9f798 100644
--- a/lib/msan/msan_interceptors.cpp
+++ b/lib/msan/msan_interceptors.cpp
@@ -765,17 +765,24 @@ INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {
#define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED
#endif
+#define INTERCEPTOR_GETRLIMIT_BODY(func, resource, rlim) \
+ if (msan_init_is_running) \
+ return REAL(getrlimit)(resource, rlim); \
+ ENSURE_MSAN_INITED(); \
+ int res = REAL(func)(resource, rlim); \
+ if (!res) \
+ __msan_unpoison(rlim, __sanitizer::struct_rlimit_sz); \
+ return res
+
INTERCEPTOR(int, getrlimit, int resource, void *rlim) {
- if (msan_init_is_running)
- return REAL(getrlimit)(resource, rlim);
- ENSURE_MSAN_INITED();
- int res = REAL(getrlimit)(resource, rlim);
- if (!res)
- __msan_unpoison(rlim, __sanitizer::struct_rlimit_sz);
- return res;
+ INTERCEPTOR_GETRLIMIT_BODY(getrlimit, resource, rlim);
}
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
+INTERCEPTOR(int, __getrlimit, int resource, void *rlim) {
+ INTERCEPTOR_GETRLIMIT_BODY(__getrlimit, resource, rlim);
+}
+
INTERCEPTOR(int, getrlimit64, int resource, void *rlim) {
if (msan_init_is_running) return REAL(getrlimit64)(resource, rlim);
ENSURE_MSAN_INITED();
@@ -806,10 +813,12 @@ INTERCEPTOR(int, prlimit64, int pid, int resource, void *new_rlimit,
return res;
}
+#define MSAN_MAYBE_INTERCEPT___GETRLIMIT INTERCEPT_FUNCTION(__getrlimit)
#define MSAN_MAYBE_INTERCEPT_GETRLIMIT64 INTERCEPT_FUNCTION(getrlimit64)
#define MSAN_MAYBE_INTERCEPT_PRLIMIT INTERCEPT_FUNCTION(prlimit)
#define MSAN_MAYBE_INTERCEPT_PRLIMIT64 INTERCEPT_FUNCTION(prlimit64)
#else
+#define MSAN_MAYBE_INTERCEPT___GETRLIMIT
#define MSAN_MAYBE_INTERCEPT_GETRLIMIT64
#define MSAN_MAYBE_INTERCEPT_PRLIMIT
#define MSAN_MAYBE_INTERCEPT_PRLIMIT64
@@ -1678,6 +1687,7 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(socketpair);
MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED;
INTERCEPT_FUNCTION(getrlimit);
+ MSAN_MAYBE_INTERCEPT___GETRLIMIT;
MSAN_MAYBE_INTERCEPT_GETRLIMIT64;
MSAN_MAYBE_INTERCEPT_PRLIMIT;
MSAN_MAYBE_INTERCEPT_PRLIMIT64;
diff --git a/test/msan/preinit_array.cpp b/test/msan/preinit_array.cpp
new file mode 100644
index 000000000..6f877bac0
--- /dev/null
+++ b/test/msan/preinit_array.cpp
@@ -0,0 +1,16 @@
+// RUN: %clangxx_msan -O0 %s -o %t && %run %t
+
+#include <sanitizer/msan_interface.h>
+
+volatile int global;
+static void pre_ctor() {
+ volatile int local;
+ global = 42;
+ local = 42;
+}
+
+__attribute__((section(".preinit_array"), used)) void(*__local_pre_ctor)(void) = pre_ctor;
+
+int main(void) {
+ return 0;
+}