Allow init to upgrade MTE to sync.
Bug: 169277947
Test: see other change in topic
Change-Id: I9f5820ffaeb23a4f5539bdbe3db1b455e45d84d8
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index 8084e73..5d5ecac 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -27,11 +27,12 @@
*/
#include "libc_init_common.h"
-#include "heap_tagging.h"
+#include <async_safe/log.h>
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -42,8 +43,8 @@
#include <sys/time.h>
#include <unistd.h>
-#include <async_safe/log.h>
-
+#include "heap_tagging.h"
+#include "private/ScopedPthreadMutexLocker.h"
#include "private/WriteProtected.h"
#include "private/bionic_defs.h"
#include "private/bionic_globals.h"
@@ -104,6 +105,51 @@
}
__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+__attribute__((no_sanitize("hwaddress", "memtag"))) void
+__libc_init_mte_late() {
+#if defined(__aarch64__)
+ if (!__libc_shared_globals()->heap_tagging_upgrade_timer_sec) {
+ return;
+ }
+ struct sigevent event = {};
+ static timer_t timer;
+ event.sigev_notify = SIGEV_THREAD;
+ event.sigev_notify_function = [](union sigval) {
+ async_safe_format_log(ANDROID_LOG_INFO, "libc",
+ "Downgrading MTE to async.");
+ ScopedPthreadMutexLocker l(&g_heap_tagging_lock);
+ SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC);
+ timer_delete(timer);
+ };
+
+ if (timer_create(CLOCK_REALTIME, &event, &timer) == -1) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "Failed to create MTE downgrade timer: %m");
+ // Revert back to ASYNC. If we fail to create or arm the timer, otherwise
+ // the process would be indefinitely stuck in SYNC.
+ SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC);
+ return;
+ }
+
+ struct itimerspec timerspec = {};
+ timerspec.it_value.tv_sec =
+ __libc_shared_globals()->heap_tagging_upgrade_timer_sec;
+ if (timer_settime(timer, /* flags= */ 0, &timerspec, nullptr) == -1) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "Failed to arm MTE downgrade timer: %m");
+ // Revert back to ASYNC. If we fail to create or arm the timer, otherwise
+ // the process would be indefinitely stuck in SYNC.
+ SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC);
+ timer_delete(timer);
+ return;
+ }
+ async_safe_format_log(
+ ANDROID_LOG_INFO, "libc", "Armed MTE downgrade timer for %" PRId64 " s",
+ __libc_shared_globals()->heap_tagging_upgrade_timer_sec);
+#endif
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
void __libc_add_main_thread() {
// Get the main thread from TLS and add it to the thread list.
pthread_internal_t* main_thread = __get_thread();