aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libc/bionic/libc_init_static.cpp35
-rw-r--r--libc/private/bionic_asm_arm64.h2
-rw-r--r--tests/Android.bp8
3 files changed, 32 insertions, 13 deletions
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index aceab38d3..815b9388f 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -191,14 +191,17 @@ bool get_config_from_env_or_sysprops(const char* env_var_name, const char* const
#ifdef __aarch64__
static bool __read_memtag_note(const ElfW(Nhdr)* note, const char* name, const char* desc,
unsigned* result) {
- if (note->n_namesz != 8 || strncmp(name, "Android", 8) != 0) {
+ if (note->n_type != NT_ANDROID_TYPE_MEMTAG) {
return false;
}
- if (note->n_type != NT_ANDROID_TYPE_MEMTAG) {
+ if (note->n_namesz != 8 || strncmp(name, "Android", 8) != 0) {
return false;
}
- if (note->n_descsz != 4) {
- async_safe_fatal("unrecognized android.memtag note: n_descsz = %d, expected 4", note->n_descsz);
+ // Previously (in Android 12), if the note was != 4 bytes, we check-failed
+ // here. Let's be more permissive to allow future expansion.
+ if (note->n_descsz < 4) {
+ async_safe_fatal("unrecognized android.memtag note: n_descsz = %d, expected >= 4",
+ note->n_descsz);
}
*result = *reinterpret_cast<const ElfW(Word)*>(desc);
return true;
@@ -285,21 +288,29 @@ static HeapTaggingLevel __get_heap_tagging_level(const void* phdr_start, size_t
unsigned note_val =
__get_memtag_note(reinterpret_cast<const ElfW(Phdr)*>(phdr_start), phdr_ct, load_bias);
- if (note_val & ~(NT_MEMTAG_LEVEL_MASK | NT_MEMTAG_HEAP)) {
- async_safe_fatal("unrecognized android.memtag note: desc = %d", note_val);
- }
+ // Note, previously (in Android 12), any value outside of bits [0..3] resulted
+ // in a check-fail. In order to be permissive of further extensions, we
+ // relaxed this restriction. For now, we still only support MTE heap.
if (!(note_val & NT_MEMTAG_HEAP)) return M_HEAP_TAGGING_LEVEL_TBI;
- unsigned memtag_level = note_val & NT_MEMTAG_LEVEL_MASK;
- switch (memtag_level) {
+ unsigned mode = note_val & NT_MEMTAG_LEVEL_MASK;
+ switch (mode) {
+ case NT_MEMTAG_LEVEL_NONE:
+ // Note, previously (in Android 12), NT_MEMTAG_LEVEL_NONE was
+ // NT_MEMTAG_LEVEL_DEFAULT, which implied SYNC mode. This was never used
+ // by anyone, but we note it (heh) here for posterity, in case the zero
+ // level becomes meaningful, and binaries with this note can be executed
+ // on Android 12 devices.
+ return M_HEAP_TAGGING_LEVEL_TBI;
case NT_MEMTAG_LEVEL_ASYNC:
return M_HEAP_TAGGING_LEVEL_ASYNC;
- case NT_MEMTAG_LEVEL_DEFAULT:
case NT_MEMTAG_LEVEL_SYNC:
- return M_HEAP_TAGGING_LEVEL_SYNC;
default:
- async_safe_fatal("unrecognized android.memtag note: level = %d", memtag_level);
+ // We allow future extensions to specify mode 3 (currently unused), with
+ // the idea that it might be used for ASYMM mode or something else. On
+ // this version of Android, it falls back to SYNC mode.
+ return M_HEAP_TAGGING_LEVEL_SYNC;
}
}
diff --git a/libc/private/bionic_asm_arm64.h b/libc/private/bionic_asm_arm64.h
index ee51a8e78..5d83d9bb5 100644
--- a/libc/private/bionic_asm_arm64.h
+++ b/libc/private/bionic_asm_arm64.h
@@ -72,7 +72,7 @@
.popsection;
#define NT_MEMTAG_LEVEL_MASK 3
-#define NT_MEMTAG_LEVEL_DEFAULT 0
+#define NT_MEMTAG_LEVEL_NONE 0
#define NT_MEMTAG_LEVEL_ASYNC 1
#define NT_MEMTAG_LEVEL_SYNC 2
#define NT_MEMTAG_HEAP 4
diff --git a/tests/Android.bp b/tests/Android.bp
index c077847fc..b30eac97f 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -1122,6 +1122,14 @@ cc_test {
lto: {
never: true,
},
+ data_bins: [
+ "heap_tagging_async_helper",
+ "heap_tagging_disabled_helper",
+ "heap_tagging_static_async_helper",
+ "heap_tagging_static_disabled_helper",
+ "heap_tagging_static_sync_helper",
+ "heap_tagging_sync_helper",
+ ],
}
// -----------------------------------------------------------------------------