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_static.cpp b/libc/bionic/libc_init_static.cpp
index 79a4019..46eafc6 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -29,6 +29,7 @@
#include <android/api-level.h>
#include <elf.h>
#include <errno.h>
+#include <malloc.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -36,10 +37,9 @@
#include <sys/auxv.h>
#include <sys/mman.h>
+#include "async_safe/log.h"
+#include "heap_tagging.h"
#include "libc_init_common.h"
-#include "pthread_internal.h"
-#include "sysprop_helpers.h"
-
#include "platform/bionic/macros.h"
#include "platform/bionic/mte.h"
#include "platform/bionic/page.h"
@@ -51,7 +51,9 @@
#include "private/bionic_elf_tls.h"
#include "private/bionic_globals.h"
#include "private/bionic_tls.h"
+#include "pthread_internal.h"
#include "sys/system_properties.h"
+#include "sysprop_helpers.h"
#if __has_feature(hwaddress_sanitizer)
#include <sanitizer/hwasan_interface.h>
@@ -302,7 +304,34 @@
void* stack_top) {
bool memtag_stack;
HeapTaggingLevel level = __get_heap_tagging_level(phdr_start, phdr_ct, load_bias, &memtag_stack);
-
+ char* env = getenv("BIONIC_MEMTAG_UPGRADE_SECS");
+ int64_t timed_upgrade = 0;
+ if (env) {
+ char* endptr;
+ timed_upgrade = strtoll(env, &endptr, 10);
+ if (*endptr != '\0' || timed_upgrade < 0) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "Invalid value for BIONIC_MEMTAG_UPGRADE_SECS: %s",
+ env);
+ timed_upgrade = 0;
+ }
+ // Make sure that this does not get passed to potential processes inheriting
+ // this environment.
+ unsetenv("BIONIC_MEMTAG_UPGRADE_SECS");
+ }
+ if (timed_upgrade) {
+ if (level == M_HEAP_TAGGING_LEVEL_ASYNC) {
+ async_safe_format_log(ANDROID_LOG_INFO, "libc",
+ "Attempting timed MTE upgrade from async to sync.");
+ __libc_shared_globals()->heap_tagging_upgrade_timer_sec = timed_upgrade;
+ level = M_HEAP_TAGGING_LEVEL_SYNC;
+ } else if (level != M_HEAP_TAGGING_LEVEL_SYNC) {
+ async_safe_format_log(
+ ANDROID_LOG_ERROR, "libc",
+ "Requested timed MTE upgrade from invalid %s to sync. Ignoring.",
+ DescribeTaggingLevel(level));
+ }
+ }
if (level == M_HEAP_TAGGING_LEVEL_SYNC || level == M_HEAP_TAGGING_LEVEL_ASYNC) {
unsigned long prctl_arg = PR_TAGGED_ADDR_ENABLE | PR_MTE_TAG_SET_NONZERO;
prctl_arg |= (level == M_HEAP_TAGGING_LEVEL_SYNC) ? PR_MTE_TCF_SYNC : PR_MTE_TCF_ASYNC;
@@ -333,6 +362,8 @@
if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == 0) {
__libc_shared_globals()->initial_heap_tagging_level = M_HEAP_TAGGING_LEVEL_TBI;
}
+ // We did not enable MTE, so we do not need to arm the upgrade timer.
+ __libc_shared_globals()->heap_tagging_upgrade_timer_sec = 0;
}
#else // __aarch64__
void __libc_init_mte(const void*, size_t, uintptr_t, void*) {}
@@ -384,6 +415,8 @@
__cxa_atexit(__libc_fini,structors->fini_array,nullptr);
}
+ __libc_init_mte_late();
+
exit(slingshot(args.argc, args.argv, args.envp));
}