aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Collingbourne <pcc@google.com>2021-07-08 00:44:24 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2021-07-08 00:44:24 +0000
commit4683b113906c6b4c252929876b16b5967aa0cbe0 (patch)
treef20b75c58f76c5e1c8a5c56058978e21702004c8
parenta44aa2e1381c9de60d287f27ac59751e7a8cc999 (diff)
parentf4f9259a1d1e0b13f06b4072516298eb574af64d (diff)
downloadbionic-4683b113906c6b4c252929876b16b5967aa0cbe0.tar.gz
Merge "Allow the kernel to upgrade ASYNC mode processes to SYNC mode." into sc-dev
-rw-r--r--libc/bionic/heap_tagging.cpp7
-rw-r--r--libc/bionic/libc_init_static.cpp6
2 files changed, 11 insertions, 2 deletions
diff --git a/libc/bionic/heap_tagging.cpp b/libc/bionic/heap_tagging.cpp
index ffbabb9a0..41aa20507 100644
--- a/libc/bionic/heap_tagging.cpp
+++ b/libc/bionic/heap_tagging.cpp
@@ -139,7 +139,12 @@ bool SetHeapTaggingLevel(HeapTaggingLevel tag_level) {
}
if (tag_level == M_HEAP_TAGGING_LEVEL_ASYNC) {
- set_tcf_on_all_threads(PR_MTE_TCF_ASYNC);
+ // When entering ASYNC mode, specify that we want to allow upgrading to SYNC by OR'ing in
+ // the SYNC flag. But if the kernel doesn't support specifying multiple TCF modes, fall back
+ // to specifying a single mode.
+ if (!set_tcf_on_all_threads(PR_MTE_TCF_ASYNC | PR_MTE_TCF_SYNC)) {
+ set_tcf_on_all_threads(PR_MTE_TCF_ASYNC);
+ }
#if defined(USE_SCUDO)
scudo_malloc_set_track_allocation_stacks(0);
#endif
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 069ebb0ab..3a8513f98 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -311,7 +311,11 @@ __attribute__((no_sanitize("hwaddress", "memtag"))) void __libc_init_mte(const v
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;
- if (prctl(PR_SET_TAGGED_ADDR_CTRL, prctl_arg, 0, 0, 0) == 0) {
+ // When entering ASYNC mode, specify that we want to allow upgrading to SYNC by OR'ing in the
+ // SYNC flag. But if the kernel doesn't support specifying multiple TCF modes, fall back to
+ // specifying a single mode.
+ if (prctl(PR_SET_TAGGED_ADDR_CTRL, prctl_arg | PR_MTE_TCF_SYNC, 0, 0, 0) == 0 ||
+ prctl(PR_SET_TAGGED_ADDR_CTRL, prctl_arg, 0, 0, 0) == 0) {
__libc_shared_globals()->initial_heap_tagging_level = level;
return;
}