Re: aarch64: Memory tagging modes proposal

Yury Khrustalev <[email protected]>
Newsgroups gmane.comp.lib.glibc.alpha
Message-ID <[email protected]>
On Mon, Aug 17, 2026 at 04:14:17PM -0300, Adhemerval Zanella Netto wrote:
> 
> 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.

It would be functional but the functionality that is "enabled" this way
would not be in fact enabled, and I don't want this to happen silently.

> > 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).

Heap stacking *can* be enabled independently, I don't argue with that.
What I am saying is that binary marking, if present, should take
precedence. So, if out of components X, Y, and Z we have marking only
for Y, we only enabled Y because this is what marking dictates. I think
this provides for a clearer interface where users know what to expect.

> > 
> > 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). 

This is already covered by the MEMTAGABI document. This part that we're
discussing here only covers the initial setup.

> 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.

I agree. This should be added to the GNU/Linux part of the MEMTAG ABI
spec.

> It means that issuing dlopen on marking DSO for a process without marking
> should return an error.

DSOs are not supposed to have DT_AARCH64_MEMTAG_{HEAP,STACK,GLOBALS}
marking according to the spec, so if they do, it's an error like you
suggest. I also agree that even if we decided to load such a DSO, we
should not alter the state of the process.

> > 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.

AFAIK, prctl flags don't have it, but if they do, we surely can support
it (now or later).

> > 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.

I don't want to add another tunable for on / off of MTE given that if
the user requests some MTE mode other than "none" they mean that MTE
should be enabled. Then the question is: What parts of Glibc should
enabled MTE support? My answer to this: in the absence of marking we
enable heap support only (but this can be extended in the future, that
is why I called it "standard" scope); if marking is present, we enable
components that are specified in the marking.

> Also, it is not clear why we need 'auto' here.

'auto' means use mode preferred by CPU as described in:
https://www.kernel.org/doc/html/next/arm64/memory-tagging-extension.html

> 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.

The idea is to allow choosing the mode via tunable. It is main purpose
of this tunable. We need this because there are going to be use cases
when people want to run *unmarked* binaries with heap tagging protection
but when they also want to switch between modes depending on their
goals. This is to support cases when we don't want or cannot rebuild a
binary every time and just want to run it in different configurations.

> > 
> > 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.

It is the default value of the tunable when it's not set explicitly.

> For 1. it
> is ignored anyway,

For 1) it not ignored. It selects the mode that the user wants to use in
this specific invocation of their program.

> and for 2. it is unclear which mode will be used
> ('mte_tcf_preferred', async).

The mode that user specifies in the tunable will be used. We can support
more modes such as asymmetric when it's supported in the prctl interface.

> > 
> > 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

Hope this clarifies it!

Thanks,
Yury
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.