Add signal to re-enable MTE for a thread
This signal handler is in Bionic (not in debuggerd) because I will
use it for the timed upgrade in a later CL.
Test: atest PermissiveMteTest
Bug: 309604766
Change-Id: I5320659ccdf8d21d1bd8bef2ab914a02f7434a83
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index ac97376..f8f7d2a 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -30,6 +30,7 @@
#include <elf.h>
#include <errno.h>
#include <malloc.h>
+#include <signal.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -293,6 +294,28 @@
return level;
}
+static void __enable_mte_signal_handler(int, siginfo_t* info, void*) {
+ if (info->si_code != SI_TIMER) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Got BIONIC_ENABLE_MTE not from SI_TIMER");
+ return;
+ }
+ int tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
+ if (tagged_addr_ctrl < 0) {
+ async_safe_fatal("failed to PR_GET_TAGGED_ADDR_CTRL: %m");
+ }
+ if ((tagged_addr_ctrl & PR_MTE_TCF_MASK) != PR_MTE_TCF_NONE) {
+ return;
+ }
+ async_safe_format_log(ANDROID_LOG_INFO, "libc",
+ "Re-enabling MTE, value: %x (tagged_addr_ctrl %lu)",
+ info->si_value.sival_int, info->si_value.sival_int & PR_MTE_TCF_MASK);
+ tagged_addr_ctrl =
+ (tagged_addr_ctrl & ~PR_MTE_TCF_MASK) | (info->si_value.sival_int & PR_MTE_TCF_MASK);
+ if (prctl(PR_SET_TAGGED_ADDR_CTRL, tagged_addr_ctrl, 0, 0, 0) < 0) {
+ async_safe_fatal("failed to PR_SET_TAGGED_ADDR_CTRL %d: %m", tagged_addr_ctrl);
+ }
+}
+
static int64_t __get_memtag_upgrade_secs() {
char* env = getenv("BIONIC_MEMTAG_UPGRADE_SECS");
if (!env) return 0;
@@ -366,7 +389,10 @@
async_safe_fatal("error: failed to set PROT_MTE on main thread stack: %m");
}
}
-
+ struct sigaction action = {};
+ action.sa_flags = SA_SIGINFO | SA_RESTART;
+ action.sa_sigaction = __enable_mte_signal_handler;
+ sigaction(BIONIC_ENABLE_MTE, &action, nullptr);
return;
}
}