summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
diff options
context:
space:
mode:
authorKostya Kortchinsky <kostyak@google.com>2017-11-20 16:39:49 +0000
committerKostya Kortchinsky <kostyak@google.com>2017-11-20 16:39:49 +0000
commita695e418f3a04069a2906b445b3a941b51259196 (patch)
tree414bb91ef8488fc69e94fe1f1d7e47573b32e8d8 /compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
parent58acafc4242377cc6a985a7b837745cbb2483fb3 (diff)
downloadbcm5719-llvm-a695e418f3a04069a2906b445b3a941b51259196.tar.gz
bcm5719-llvm-a695e418f3a04069a2906b445b3a941b51259196.zip
[sanitizer] New attempt at using runtime checks for Android logging
Summary: This is a second attempt after D40100 induced racey crashes with ASan (due to `__android_log_write` and the `strncpy` interceptor on API >= 21). This new version checks the runtime API level to be <= `ANDROID_KITKAT` for the use of `__android_log_write`, otherwise we use `syslog`, which should conform with the previous behavior. Unfortunately despite numerous efforts I couldn't reproduce the original crashes in my environments so I couldn't test that the fix was actually preventing crashes. Reviewers: eugenis Reviewed By: eugenis Subscribers: llvm-commits, srhines, kubamracek Differential Revision: https://reviews.llvm.org/D40149 llvm-svn: 318659
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc')
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc67
1 files changed, 40 insertions, 27 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
index b298fe4c55b..6fc1396ab81 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -48,10 +48,6 @@
#include <android/api-level.h>
#endif
-#if SANITIZER_ANDROID && __ANDROID_API__ < 21
-#include <android/log.h>
-#endif
-
#if !SANITIZER_ANDROID
#include <elf.h>
#include <unistd.h>
@@ -536,12 +532,9 @@ uptr GetRSS() {
return rss * GetPageSizeCached();
}
-// 64-bit Android targets don't provide the deprecated __android_log_write.
-// Starting with the L release, syslog() works and is preferable to
-// __android_log_write.
#if SANITIZER_LINUX
-#if SANITIZER_ANDROID
+# if SANITIZER_ANDROID
static atomic_uint8_t android_log_initialized;
void AndroidLogInit() {
@@ -552,35 +545,55 @@ void AndroidLogInit() {
static bool ShouldLogAfterPrintf() {
return atomic_load(&android_log_initialized, memory_order_acquire);
}
-#else
-void AndroidLogInit() {}
-static bool ShouldLogAfterPrintf() { return true; }
-#endif // SANITIZER_ANDROID
+extern "C" SANITIZER_WEAK_ATTRIBUTE
+int async_safe_write_log(int pri, const char* tag, const char* msg);
+extern "C" SANITIZER_WEAK_ATTRIBUTE
+int __android_log_write(int prio, const char* tag, const char* msg);
+
+// ANDROID_LOG_INFO is 4, but can't be resolved at runtime.
+#define SANITIZER_ANDROID_LOG_INFO 4
+// async_safe_write_log is a new public version of __libc_write_log that is
+// used behind syslog. It is preferable to syslog as it will not do any dynamic
+// memory allocation or formatting.
+// If the function is not available, syslog is preferred for L+ (it was broken
+// pre-L) as __android_log_write triggers a racey behavior with the strncpy
+// interceptor. Fallback to __android_log_write pre-L.
void WriteOneLineToSyslog(const char *s) {
-#if SANITIZER_ANDROID &&__ANDROID_API__ < 21
- __android_log_write(ANDROID_LOG_INFO, NULL, s);
-#else
- syslog(LOG_INFO, "%s", s);
-#endif
+ if (&async_safe_write_log) {
+ async_safe_write_log(SANITIZER_ANDROID_LOG_INFO, GetProcessName(), s);
+ } else if (AndroidGetApiLevel() > ANDROID_KITKAT) {
+ syslog(LOG_INFO, "%s", s);
+ } else {
+ CHECK(&__android_log_write);
+ __android_log_write(SANITIZER_ANDROID_LOG_INFO, nullptr, s);
+ }
}
-void LogMessageOnPrintf(const char *str) {
- if (common_flags()->log_to_syslog && ShouldLogAfterPrintf())
- WriteToSyslog(str);
-}
+extern "C" SANITIZER_WEAK_ATTRIBUTE
+void android_set_abort_message(const char *);
-#if SANITIZER_ANDROID
-extern "C" __attribute__((weak)) void android_set_abort_message(const char *);
void SetAbortMessage(const char *str) {
- if (&android_set_abort_message) android_set_abort_message(str);
+ if (&android_set_abort_message)
+ android_set_abort_message(str);
}
-#else
+# else
+void AndroidLogInit() {}
+
+static bool ShouldLogAfterPrintf() { return true; }
+
+void WriteOneLineToSyslog(const char *s) { syslog(LOG_INFO, "%s", s); }
+
void SetAbortMessage(const char *str) {}
-#endif
+# endif // SANITIZER_ANDROID
+
+void LogMessageOnPrintf(const char *str) {
+ if (common_flags()->log_to_syslog && ShouldLogAfterPrintf())
+ WriteToSyslog(str);
+}
-#endif // SANITIZER_LINUX
+#endif // SANITIZER_LINUX
} // namespace __sanitizer
OpenPOWER on IntegriCloud