From e720cc213f13979d9ff0c47dce041b83192bc8de Mon Sep 17 00:00:00 2001 From: Mitch Phillips <31459023+hctim@users.noreply.github.com> Date: Mon, 9 Oct 2023 10:29:36 +0200 Subject: [PATCH] Change MEMTAG_STACK to be d_val, and MEMTAG_GLOBALS to be d_ptr MEMTAG_STACK should be d_val (a bit to indicate that MTE stack is either on/off), and MEMTAG_GLOBALS should be d_ptr (a pointer offset to a section containing memtag globals descriptors). This is the way that lld has implemented it, as it's the local semantics (MEMTAG_GLOBALS is a pointer-to-section that needs load bias adjustment, and MEMTAG_STACK is a single bit that enables PROT_MTE on the stack). This unfortunatly does mean that we diverge from the accepted semantics of odd == d_val, and even == d_ptr, but this seems like the best trade-off as we've shipped a compiler that did the non-spec-but-more-logical thing and shipped binaries to end users. Much better than shipping a whole new set of MEMTAG_GLOBALS_2 and MEMTAG_STACK_2 to fix the mistake. Found by eugenis@ in https://r.android.com/2765590 --- memtagabielf64/memtagabielf64.rst | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/memtagabielf64/memtagabielf64.rst b/memtagabielf64/memtagabielf64.rst index bd6e093..3dec531 100644 --- a/memtagabielf64/memtagabielf64.rst +++ b/memtagabielf64/memtagabielf64.rst @@ -366,13 +366,30 @@ MemtagABI adds the following processor-specific dynamic array tags: +---------------------------------+------------+--------+-------------------+-------------------+ | ``DT_AARCH64_MEMTAG_HEAP`` | 0x7000000b | d\_val | Platform specific | Platform Specific | +---------------------------------+------------+--------+-------------------+-------------------+ - | ``DT_AARCH64_MEMTAG_STACK`` | 0x7000000c | d\_ptr | Platform specific | Platform Specific | + | ``DT_AARCH64_MEMTAG_STACK`` | 0x7000000c | d\_val | Platform specific | Platform Specific | +---------------------------------+------------+--------+-------------------+-------------------+ - | ``DT_AARCH64_MEMTAG_GLOBALS`` | 0x7000000d | d\_val | Platform specific | Platform Specific | + | ``DT_AARCH64_MEMTAG_GLOBALS`` | 0x7000000d | d\_ptr | Platform specific | Platform Specific | +---------------------------------+------------+--------+-------------------+-------------------+ | ``DT_AARCH64_MEMTAG_GLOBALSSZ`` | 0x7000000f | d\_val | Platform specific | Platform Specific | +---------------------------------+------------+--------+-------------------+-------------------+ +.. warning:: + + Earlier revisions of this document had ``DT_AARCH64_MEMTAG_STACK`` and + ``DT_AARCH64_MEMTAG_GLOBALS`` with incorrect ``d_un`` (``d_ptr`` and ``d_val`` + respectively). Binaries compiled with clang-17 and lld-17 produced the dynamic + entries with ``DT_AARCH64_MEMTAG_STACK`` as ``d_val`` and + ``DT_AARCH64_MEMTAG_GLOBALS`` as ``d_ptr`` as this was the intended semantics, + and they were shipped on Android devices. The values were thus updated to + their more fitting semantic types (without updating the ``Value``), but this + does mean that ``DT_AARCH64_MEMTAG_STACK`` is a ``d_val`` with an even + ``Value``, and ``DT_AARCH64_MEMTAG_GLOBALS`` is a ``d_ptr`` with an odd + ``Value`` (where the normal semantics are ``odd == d_val``, and ``even == + d_ptr``). Implementations of dynamic loaders need to be careful to apply these + semantics correctly - notably the load bias should not be applied to + ``DT_AARCH64_MEMTAG_STACK``, as it's a ``d_val``, even though the ``Value`` is + even. + ``DT_AARCH64_MEMTAG_MODE`` indicates the initial MTE mode that should be set. It has two possible values: ``0``, indicating that the desired MTE mode is Synchronous, and ``1``, indicating that the desired mode is Asynchronous. This