aarch64: Memory tagging modes proposal

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Mon Aug 17 19:14:17 GMT 2026



On 11/08/26 10:40, Yury Khrustalev wrote:
> Request for feedback.
> 
> This is a proposal for how MTE binary marking from [1] should co-exist with
> the MTE Glibc tunable (not yet implemented). In my opinion, both are necessary
> to cover all practical use cases and provide both flexibility of future
> experiments and ease of configuration for developers and end users. This
> explain how it all should work.
> 

Hi Yury,

I did a POC to check how it would play with glibc [1], mostly to check how
to simplify the first MTE proposal but also to check if current ideas from
other system would make sense for glibc. 

> [1]: https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst
> 
> The set of rules below:
> 
> 1) Respects binary marking when it's present.
> 2) Tunable cannot disable tagging, only change MTE mode.
> 3) What kind of memory tagging is enabled (i.e. the scope) is solely
>    determined either by the binary marking (when it's present) or by
>    the tunable (when marking is not present).
> 4) You cannot enable stack and globals tagging unless corresponding
>    binary marking is present (it requires support by compiler and static
>    linker), but you can choose if you enable heap tagging for unmarked
>    binaries.

Afaiu it should be *functional* safe to enable MTE even though the process itself
does not issue any MTE instructions.  It would incur in the performance hit
(kernel-side page cost, non-KSM merging, extra DRAM usage), but it would be a way
to make non-marked binaries to allow dlopen marked DSO.

> 5) If you want heap tagging for marked binaries, the DT_AARCH64_MEMTAG_HEAP
>    tag must be set explicitly.

I think different than DT_AARCH64_MEMTAG_STACK, DT_AARCH64_MEMTAG_HEAP can be
enabled independently whether the process has the marking or not. Afaiu it is
property of the malloc implementation instead of the binary (different than
the stack support).

> 
> Binary marking:
>  - DT_AARCH64_MEMTAG_MODE=0|1: selects fault mode for MTE memory tag
>    checking, i.e. MTE mode.
>  - DT_AARCH64_MEMTAG_{HEAP,STACK,GLOBALS} determines the scope of
>    memory tagging.

I think it would be worth to add that MTE state should be setup at program
*startup* and it should not be changed during process execution (like by
dlopen). I don't think we should replicate bionic's DT_AARCH64_MEMTAG_STACK
support, where it enables MTE support for running threads if a DSO required
it.

It means that issuing dlopen on marking DSO for a process without marking
should return an error.
> 
> Tunable:
>  - glibc.cpu.mtemode=none|auto|sync|async: selects fault mode for MTE
>    memory tag checking (also see below), default value is 'none'.

Should we consider asymm mode? This is not defined by the ABI but it supported
by Linux and defined for ARM v8.7.

> 
> If both the tunable and the DT_AARCH64_MEMTAG_MODE tag are explicitly
> set, the tunable takes precedence (allows to override mode that is built
> into the binary) except when tunable is set to 'none' in which case the
> tunable has no effect.
> 
> Tunable cannot disable MTE memory tagging when binary marking requires it,
> it can only change the mode.
> 
> If none of DT_AARCH64_MEMTAG_{HEAP,STACK,GLOBALS} is present, the tunable,
> when set to a value other than 'none', will enable the "standard" set of
> memory tagging features (currently HEAP).

I think this a bit confusing, where it mixes the MTE mode (auto, sync, async)
with a MTE support. 

Also, it is not clear why we need 'auto' here. The ISA required 'async' to be
supported, and without DT_AARCH64_MEMTAG_MODE it is the default. I think in
the absence of the mode marking we can just use the 'mte_tcf_preferred'
setting.

> 
> If DT_AARCH64_MEMTAG_MODE is not present and the mode has to be inferred
> from the binary marking (i.e. in the absence of the tunable), the default
> value for the mode is 'auto'.
> 
>  1) No binary marking: when none of the DT_AARCH64_MEMTAG_{HEAP,STACK,GLOBALS}
>     tags are present:
> 
>   | Tunable | MEMTAG_MODE | Status | Mode  | Scope     |
>   |----------------------------------------------------|
>   | (unset) | (ignored)   | off    |  --   | --        |
>   | none    | (ignored)   | off    |  --   | --        |
>   | auto    | (ignored)   | on     | auto  | standard  |
>   | sync    | (ignored)   | on     | sync  | standard  |
>   | async   | (ignored)   | on     | async | standard  |
> >  2) When DT_AARCH64_MEMTAG_{HEAP,STACK,GLOBALS} are present (at least
>     one of them):
> 
>   | Tunable | MEMTAG_MODE | Status | Mode  | Scope     |
>   |----------------------------------------------------|
>   | (unset) | (unset)     | on     | auto  | (marking) |
>   | (unset) | 0           | on     | sync  | (marking) |
>   | (unset) | 1           | on     | async | (marking) |
>   | none    | (unset)     | on     | auto  | (marking) |
>   | none    | 0           | on     | sync  | (marking) |
>   | none    | 1           | on     | async | (marking) |
>   | auto    | (ignored)   | on     | auto  | (marking) |
>   | sync    | (ignored)   | on     | sync  | (marking) |
>   | async   | (ignored)   | on     | async | (marking) |
> 
> In the table above, '(marking)' means whatever components are flagged with
> the DT_AARCH64_MEMTAG_{HEAP,STACK,GLOBALS} tags and are supported by the
> current version of Glibc.

It still not clear what the 'none' tunable mode improves here. For 1. it
is ignored anyway, and for 2. it is unclear which mode will be used
('mte_tcf_preferred', async).

> 
> Status 'on' means that the prctl(PR_TAGGED_ADDR_ENABLE) will be made at the
> start of the process. The mode is included in the flags for this syscall.
> 
> The Scope determines which parts of the tagging implementation in Glibc
> are actually activated.
> 
> This may appear complicated however this is due to the difference of how
> heap tagging is implemented compared to tagging of stack and globals. In
> the latter case binary needs to be built with necessary instrumentation
> that is not controlled by Glibc.
> 
> Any feedback welcome!
[1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/aarch64-memtag


More information about the Libc-alpha mailing list