Merge "Allow init to upgrade MTE to sync."
This commit is contained in:
commit
ea7f84435d
|
@ -43,3 +43,19 @@ extern pthread_mutex_t g_heap_tagging_lock;
|
|||
// This function can be called in a multithreaded context, and thus should
|
||||
// only be called when holding the `g_heap_tagging_lock`.
|
||||
bool SetHeapTaggingLevel(HeapTaggingLevel level);
|
||||
|
||||
// This is static because libc_nomalloc uses this but does not need to link the
|
||||
// cpp file.
|
||||
__attribute__((unused)) static inline const char* DescribeTaggingLevel(
|
||||
HeapTaggingLevel level) {
|
||||
switch (level) {
|
||||
case M_HEAP_TAGGING_LEVEL_NONE:
|
||||
return "none";
|
||||
case M_HEAP_TAGGING_LEVEL_TBI:
|
||||
return "tbi";
|
||||
case M_HEAP_TAGGING_LEVEL_ASYNC:
|
||||
return "async";
|
||||
case M_HEAP_TAGGING_LEVEL_SYNC:
|
||||
return "sync";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
@ -103,6 +104,51 @@ void __libc_init_scudo() {
|
|||
#endif
|
||||
}
|
||||
|
||||
__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.
|
||||
|
|
|
@ -60,6 +60,8 @@ __LIBC_HIDDEN__ void __libc_init_common();
|
|||
|
||||
__LIBC_HIDDEN__ void __libc_init_scudo();
|
||||
|
||||
__LIBC_HIDDEN__ void __libc_init_mte_late();
|
||||
|
||||
__LIBC_HIDDEN__ void __libc_init_AT_SECURE(char** envp);
|
||||
|
||||
// The fork handler must be initialised after __libc_init_malloc, as
|
||||
|
|
|
@ -154,6 +154,8 @@ __noreturn void __libc_init(void* raw_args,
|
|||
__cxa_atexit(__libc_fini,structors->fini_array,nullptr);
|
||||
}
|
||||
|
||||
__libc_init_mte_late();
|
||||
|
||||
exit(slingshot(args.argc - __libc_shared_globals()->initial_linker_arg_count,
|
||||
args.argv + __libc_shared_globals()->initial_linker_arg_count,
|
||||
args.envp));
|
||||
|
|
|
@ -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 @@ __attribute__((no_sanitize("hwaddress", "memtag"))) void __libc_init_mte(const v
|
|||
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 @@ __attribute__((no_sanitize("hwaddress", "memtag"))) void __libc_init_mte(const v
|
|||
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 @@ __attribute__((no_sanitize("memtag"))) __noreturn static void __real_libc_init(
|
|||
__cxa_atexit(__libc_fini,structors->fini_array,nullptr);
|
||||
}
|
||||
|
||||
__libc_init_mte_late();
|
||||
|
||||
exit(slingshot(args.argc, args.argv, args.envp));
|
||||
}
|
||||
|
||||
|
|
|
@ -29,19 +29,19 @@
|
|||
#ifndef _PRIVATE_BIONIC_GLOBALS_H
|
||||
#define _PRIVATE_BIONIC_GLOBALS_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <link.h>
|
||||
#include <platform/bionic/malloc.h>
|
||||
#include <pthread.h>
|
||||
#include <stdatomic.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <link.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "private/WriteProtected.h"
|
||||
#include "private/bionic_allocator.h"
|
||||
#include "private/bionic_elf_tls.h"
|
||||
#include "private/bionic_fdsan.h"
|
||||
#include "private/bionic_malloc_dispatch.h"
|
||||
#include "private/bionic_vdso.h"
|
||||
#include "private/WriteProtected.h"
|
||||
|
||||
#include <platform/bionic/malloc.h>
|
||||
|
||||
struct libc_globals {
|
||||
vdso_entry vdso[VDSO_END];
|
||||
|
@ -114,6 +114,7 @@ struct libc_shared_globals {
|
|||
|
||||
HeapTaggingLevel initial_heap_tagging_level = M_HEAP_TAGGING_LEVEL_NONE;
|
||||
bool initial_memtag_stack = false;
|
||||
int64_t heap_tagging_upgrade_timer_sec = 0;
|
||||
};
|
||||
|
||||
__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals();
|
||||
|
|
Loading…
Reference in New Issue