* [PATCH 0/2] RFC: Support for MTE stack tagging.
@ 2025-03-14 13:21 Cupertino Miranda
2025-03-14 13:21 ` [PATCH 1/2] rtld: Enable MTE for stack when specified in .dynamic Cupertino Miranda
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: Cupertino Miranda @ 2025-03-14 13:21 UTC (permalink / raw)
To: libc-alpha
Cc: jose.marchesi, elena.zannoni, richard.sandiford, Cupertino Miranda
Hi everyone,
This is an initial work to enable glibc support for MTE stack tagging.
In a nutshell glibc should set PROT_MTE to any stack pages which get
allocated for any running application which requires MTE stack tagging.
The approach taken to flag the need for stack tagging is to check
.dynamic entries specific to aarch64, as described in section 6 from:
https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst
This is an initial propose patch. I would like to get some feedback
for the approach used to check for the .dynamic flags, how the
PROT_MTE property is set for the stacks or any other comments.
This feature is related to the work done by Indu Bhagat submitted as RFC
in gcc-patches:
https://gcc.gnu.org/pipermail/gcc-patches/2024-November/668017.html
And in binutils in:
https://sourceware.org/pipermail/binutils/2024-December/137989.html
I noticed my patches fail a lot of conform/linknamespace tests. I
think I need some guidance for why this happens.
Looking forward to your comments.
Best regards,
Cupertino
Cupertino Miranda (2):
rtld: Enable MTE for stack when specified in .dynamic.
nptl: Enable MTE for stacks created for threads.
elf/dl-mte-stack.c | 28 +++++++
elf/elf.h | 8 +-
nptl/allocatestack.c | 3 +-
nptl/nptl-stack.c | 7 ++
nptl/nptl-stack.h | 2 +
sysdeps/aarch64/Makefile | 3 +-
sysdeps/aarch64/cpu-features.h | 15 ++++
sysdeps/aarch64/dl-mte.c | 50 +++++++++++
sysdeps/aarch64/dl-prop.h | 4 +
sysdeps/unix/sysv/linux/aarch64/Makefile | 10 +++
.../unix/sysv/linux/aarch64/dl-mte-stack.c | 83 +++++++++++++++++++
11 files changed, 210 insertions(+), 3 deletions(-)
create mode 100644 elf/dl-mte-stack.c
create mode 100644 sysdeps/aarch64/dl-mte.c
create mode 100644 sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c
--
2.39.5
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/2] rtld: Enable MTE for stack when specified in .dynamic.
2025-03-14 13:21 [PATCH 0/2] RFC: Support for MTE stack tagging Cupertino Miranda
@ 2025-03-14 13:21 ` Cupertino Miranda
2025-03-19 19:05 ` Adhemerval Zanella Netto
2025-03-14 13:21 ` [PATCH 2/2] nptl: Enable MTE for stacks created for threads Cupertino Miranda
` (2 subsequent siblings)
3 siblings, 1 reply; 11+ messages in thread
From: Cupertino Miranda @ 2025-03-14 13:21 UTC (permalink / raw)
To: libc-alpha
Cc: jose.marchesi, elena.zannoni, richard.sandiford, Cupertino Miranda
MTE stack tagging enabled executables are flagged by setting the dynamic
array tag DT_AARCH64_MEMTAG_STACK as described in section 6 from:
https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst
Also the mode in which MTE would react to MTE faults is set by the tag
DT_AARCH64_MEMTAG_MODE.
This patch verifies for the presence of those tags in the dynamic array
and performs mprotect on the main application stack map with the extra
PROT_MTE flag.
---
elf/dl-mte-stack.c | 27 +++++++
elf/elf.h | 8 +-
sysdeps/aarch64/Makefile | 3 +-
sysdeps/aarch64/cpu-features.h | 15 ++++
sysdeps/aarch64/dl-mte.c | 50 +++++++++++++
sysdeps/aarch64/dl-prop.h | 4 +
sysdeps/unix/sysv/linux/aarch64/Makefile | 5 ++
.../unix/sysv/linux/aarch64/dl-mte-stack.c | 74 +++++++++++++++++++
8 files changed, 184 insertions(+), 2 deletions(-)
create mode 100644 elf/dl-mte-stack.c
create mode 100644 sysdeps/aarch64/dl-mte.c
create mode 100644 sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c
diff --git a/elf/dl-mte-stack.c b/elf/dl-mte-stack.c
new file mode 100644
index 0000000000..f0063b54a0
--- /dev/null
+++ b/elf/dl-mte-stack.c
@@ -0,0 +1,27 @@
+/* Stack memory tagging support. Stub version.
+ Copyright (C) 2003-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <ldsodefs.h>
+#include <errno.h>
+
+void
+_dl_mte_stack_protect (void *stack_end)
+{
+ return ENOSYS;
+}
+rtld_hidden_def (_dl_mte_stack_protect)
diff --git a/elf/elf.h b/elf/elf.h
index 96df2eec01..daf0e52b15 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -1392,6 +1392,7 @@ typedef struct
#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0)
#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1)
#define GNU_PROPERTY_AARCH64_FEATURE_1_GCS (1U << 2)
+#define GNU_PROPERTY_AARCH64_FEATURE_1_MTE_STACK (1U << 3)
/* The x86 instruction sets indicated by the corresponding bits are
used in program. Their support in the hardware is optional. */
@@ -3049,7 +3050,12 @@ enum
#define DT_AARCH64_BTI_PLT (DT_LOPROC + 1)
#define DT_AARCH64_PAC_PLT (DT_LOPROC + 3)
#define DT_AARCH64_VARIANT_PCS (DT_LOPROC + 5)
-#define DT_AARCH64_NUM 6
+#define DT_AARCH64_MEMTAG_MODE (DT_LOPROC + 9)
+#define DT_AARCH64_MEMTAG_HEAP (DT_LOPROC + 11)
+#define DT_AARCH64_MEMTAG_STACK (DT_LOPROC + 12)
+#define DT_AARCH64_MEMTAG_GLOBALS (DT_LOPROC + 13)
+#define DT_AARCH64_MEMTAG_GLOBALSSZ (DT_LOPROC + 15)
+#define DT_AARCH64_NUM 16
/* AArch64 specific values for the st_other field. */
#define STO_AARCH64_VARIANT_PCS 0x80
diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile
index 4b7f8a5c07..f93ef636ac 100644
--- a/sysdeps/aarch64/Makefile
+++ b/sysdeps/aarch64/Makefile
@@ -11,7 +11,8 @@ endif
ifeq ($(subdir),elf)
sysdep-dl-routines += \
dl-bti \
- dl-gcs
+ dl-gcs \
+ dl-mte
tests += tst-audit26 \
tst-audit27
diff --git a/sysdeps/aarch64/cpu-features.h b/sysdeps/aarch64/cpu-features.h
index ef4e947e8c..0761549718 100644
--- a/sysdeps/aarch64/cpu-features.h
+++ b/sysdeps/aarch64/cpu-features.h
@@ -66,4 +66,19 @@ struct cpu_features
bool mops;
};
+#define ARCH_MTE_MODE_SYNC (1 << 1)
+#define ARCH_MTE_MODE_ASYNC (1 << 2)
+#define AARCH64_CPU_FEATURE_MTE_STATE_STACK (1 << 3)
+
+#define AARCH64_CPU_FEATURE_MTE_STATE_MODE_MASK (0x3)
+
+#define AARCH64_CPU_FEATURE_MTE_STATE_MODE_MASK (0x3)
+#define AARCH64_CPU_FEATURE_MTE_STATE_MODE_ASYNC (1)
+#define AARCH64_CPU_FEATURE_MTE_STATE_MODE_SYNC (1 << 1)
+
+
+#ifndef ARCH_INIT_MEMORY_STACK_TAGGING
+#define ARCH_INIT_MEMORY_STACK_TAGGING _dl_mte_stack_protect
+#endif
+
#endif /* _CPU_FEATURES_AARCH64_H */
diff --git a/sysdeps/aarch64/dl-mte.c b/sysdeps/aarch64/dl-mte.c
new file mode 100644
index 0000000000..30740d1eca
--- /dev/null
+++ b/sysdeps/aarch64/dl-mte.c
@@ -0,0 +1,50 @@
+/* AArch64 MTE Stack functions.
+ Copyright (C) 2020-2025 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <assert.h>
+
+extern void
+_dl_mte_stack_protect (void *stack_end);
+
+void
+_dl_mte_stack_check (struct link_map *l, const char *program)
+{
+ /* TODO: Replace the dynamic info by gnu.property entry. */
+ ElfW(Dyn) *d;
+ for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
+ {
+ if (d->d_tag == DT_AARCH64_MEMTAG_STACK)
+ GLRO(dl_aarch64_cpu_features).mte_state |= AARCH64_CPU_FEATURE_MTE_STATE_STACK;
+ if (d->d_tag == DT_AARCH64_MEMTAG_MODE)
+ {
+ if (d->d_un.d_val == 1)
+ {
+ GLRO(dl_aarch64_cpu_features).mte_state &= ~AARCH64_CPU_FEATURE_MTE_STATE_MODE_MASK;
+ GLRO(dl_aarch64_cpu_features).mte_state |= AARCH64_CPU_FEATURE_MTE_STATE_MODE_ASYNC;
+ }
+ else
+ {
+ GLRO(dl_aarch64_cpu_features).mte_state &= ~AARCH64_CPU_FEATURE_MTE_STATE_MODE_MASK;
+ GLRO(dl_aarch64_cpu_features).mte_state |= AARCH64_CPU_FEATURE_MTE_STATE_MODE_ASYNC;
+ }
+ }
+ }
+
+ _dl_mte_stack_protect (__libc_stack_end);
+}
diff --git a/sysdeps/aarch64/dl-prop.h b/sysdeps/aarch64/dl-prop.h
index abca2be7fa..66b05c1b75 100644
--- a/sysdeps/aarch64/dl-prop.h
+++ b/sysdeps/aarch64/dl-prop.h
@@ -27,11 +27,15 @@ extern void _dl_bti_check (struct link_map *, const char *)
extern void _dl_gcs_check (struct link_map *, const char *)
attribute_hidden;
+extern void _dl_mte_stack_check (struct link_map *, const char *)
+ attribute_hidden;
+
static inline void __attribute__ ((always_inline))
_rtld_main_check (struct link_map *m, const char *program)
{
_dl_bti_check (m, program);
_dl_gcs_check (m, program);
+ _dl_mte_stack_check (m, program);
}
static inline void __attribute__ ((always_inline))
diff --git a/sysdeps/unix/sysv/linux/aarch64/Makefile b/sysdeps/unix/sysv/linux/aarch64/Makefile
index 1fdad67fae..8fb0e65b2a 100644
--- a/sysdeps/unix/sysv/linux/aarch64/Makefile
+++ b/sysdeps/unix/sysv/linux/aarch64/Makefile
@@ -5,6 +5,11 @@ tests += \
# tests
endif
+ifeq ($(subdir),elf)
+sysdep-dl-routines += \
+ dl-mte-stack
+endif
+
ifeq ($(subdir),stdlib)
gen-as-const-headers += ucontext_i.sym
endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c b/sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c
new file mode 100644
index 0000000000..a4bc82c99b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c
@@ -0,0 +1,74 @@
+/* Memory tagging handling for GNU dynamic linker. Stub version.
+ Copyright (C) 2003-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <ldsodefs.h>
+#include <libintl.h>
+#include <not-cancel.h>
+#include <sys/prctl.h>
+
+#define MTE_ALLOWED_TAGS (0xfffe << PR_MTE_TAG_SHIFT)
+
+static int
+_dl_mte_mode (void)
+{
+ if (GLRO(dl_aarch64_cpu_features).mte_state & AARCH64_CPU_FEATURE_MTE_STATE_MODE_SYNC)
+ __prctl (PR_SET_TAGGED_ADDR_CTRL,
+ (PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | MTE_ALLOWED_TAGS),
+ 0, 0, 0);
+ else if (GLRO(dl_aarch64_cpu_features).mte_state & AARCH64_CPU_FEATURE_MTE_STATE_MODE_ASYNC)
+ __prctl (PR_SET_TAGGED_ADDR_CTRL,
+ (PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_ASYNC | MTE_ALLOWED_TAGS),
+ 0, 0, 0);
+
+ return ((GLRO(dl_aarch64_cpu_features).mte_state & AARCH64_CPU_FEATURE_MTE_STATE_MODE_MASK) != 0);
+}
+
+void
+_dl_mte_stack_protect (void *stack_end)
+{
+ if ((GLRO(dl_aarch64_cpu_features).mte_state & AARCH64_CPU_FEATURE_MTE_STATE_STACK) == 0
+ || !_dl_mte_mode ())
+ return;
+
+ int errval = 0;
+ uintptr_t page = ((uintptr_t) stack_end
+ & -(intptr_t) GLRO(dl_pagesize));
+
+ if (__mprotect ((void *) page, GLRO(dl_pagesize),
+ PROT_READ | PROT_WRITE | PROT_MTE
+ | (GL(dl_stack_flags) & PF_X ? PROT_EXEC : 0)
+#if _STACK_GROWS_DOWN
+ | PROT_GROWSDOWN
+#elif _STACK_GROWS_UP
+ | PROT_GROWSUP
+#endif
+ ) != 0)
+ errval = errno;
+
+ if (errval)
+ {
+ const char *errstring = NULL;
+ errstring = N_("\
+cannot set stack with PROT_MTE");
+ const char *name = "MTE Stack";
+ struct dl_exception exception;
+ _dl_exception_create (&exception, name, errstring);
+ _dl_signal_exception (errval, &exception, NULL);
+ }
+}
+
--
2.39.5
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/2] nptl: Enable MTE for stacks created for threads.
2025-03-14 13:21 [PATCH 0/2] RFC: Support for MTE stack tagging Cupertino Miranda
2025-03-14 13:21 ` [PATCH 1/2] rtld: Enable MTE for stack when specified in .dynamic Cupertino Miranda
@ 2025-03-14 13:21 ` Cupertino Miranda
2025-03-14 16:35 ` Florian Weimer
2025-03-19 19:35 ` Adhemerval Zanella Netto
2025-03-14 13:31 ` [PATCH 0/2] RFC: Support for MTE stack tagging Cupertino Miranda
2025-03-14 16:33 ` Florian Weimer
3 siblings, 2 replies; 11+ messages in thread
From: Cupertino Miranda @ 2025-03-14 13:21 UTC (permalink / raw)
To: libc-alpha
Cc: jose.marchesi, elena.zannoni, richard.sandiford, Cupertino Miranda
This patch adds MPROT_MTE flag to newly mapped stacks for threads, if
DT_AARCH64_MEMTAG_STACK is present in the array of dynamic tags in the
executable.
---
elf/dl-mte-stack.c | 1 +
nptl/allocatestack.c | 3 ++-
nptl/nptl-stack.c | 7 +++++++
nptl/nptl-stack.h | 2 ++
sysdeps/unix/sysv/linux/aarch64/Makefile | 5 +++++
sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c | 11 ++++++++++-
6 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/elf/dl-mte-stack.c b/elf/dl-mte-stack.c
index f0063b54a0..f5b8293c7a 100644
--- a/elf/dl-mte-stack.c
+++ b/elf/dl-mte-stack.c
@@ -25,3 +25,4 @@ _dl_mte_stack_protect (void *stack_end)
return ENOSYS;
}
rtld_hidden_def (_dl_mte_stack_protect)
+
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index 800ca89720..6155157063 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -153,7 +153,8 @@ static int allocate_stack_mode = ALLOCATE_GUARD_MADV_GUARD;
static inline int stack_prot (void)
{
return (PROT_READ | PROT_WRITE
- | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0));
+ | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0)
+ | stack_mem_tagging_prot ());
}
static void *
diff --git a/nptl/nptl-stack.c b/nptl/nptl-stack.c
index c049c5133c..34fbba1cd1 100644
--- a/nptl/nptl-stack.c
+++ b/nptl/nptl-stack.c
@@ -145,3 +145,10 @@ __pthread_get_minstack (const pthread_attr_t *attr)
+ PTHREAD_STACK_MIN);
}
libc_hidden_def (__pthread_get_minstack)
+
+int
+__stack_mem_tagging_prot (void)
+{
+ return 0;
+}
+weak_alias (__stack_mem_tagging_prot, stack_mem_tagging_prot)
diff --git a/nptl/nptl-stack.h b/nptl/nptl-stack.h
index ac672e16cf..2bfcaf7252 100644
--- a/nptl/nptl-stack.h
+++ b/nptl/nptl-stack.h
@@ -61,4 +61,6 @@ __nptl_tls_static_size_for_stack (void)
return roundup (GLRO (dl_tls_static_size), GLRO (dl_tls_static_align));
}
+int stack_mem_tagging_prot (void);
+
#endif /* _NPTL_STACK_H */
diff --git a/sysdeps/unix/sysv/linux/aarch64/Makefile b/sysdeps/unix/sysv/linux/aarch64/Makefile
index 8fb0e65b2a..e91a756836 100644
--- a/sysdeps/unix/sysv/linux/aarch64/Makefile
+++ b/sysdeps/unix/sysv/linux/aarch64/Makefile
@@ -10,6 +10,11 @@ sysdep-dl-routines += \
dl-mte-stack
endif
+ifeq ($(subdir),nptl)
+routines += \
+ dl-mte-stack
+endif
+
ifeq ($(subdir),stdlib)
gen-as-const-headers += ucontext_i.sym
endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c b/sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c
index a4bc82c99b..7ed92855ae 100644
--- a/sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c
+++ b/sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c
@@ -42,7 +42,7 @@ void
_dl_mte_stack_protect (void *stack_end)
{
if ((GLRO(dl_aarch64_cpu_features).mte_state & AARCH64_CPU_FEATURE_MTE_STATE_STACK) == 0
- || !_dl_mte_mode ())
+ || !_dl_mte_mode ())
return;
int errval = 0;
@@ -72,3 +72,12 @@ cannot set stack with PROT_MTE");
}
}
+int
+stack_mem_tagging_prot (void)
+{
+ if ((GLRO(dl_aarch64_cpu_features).mte_state & AARCH64_CPU_FEATURE_MTE_STATE_STACK) == 8
+ && _dl_mte_mode ())
+ return PROT_MTE;
+ else
+ return 0;
+}
--
2.39.5
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 0/2] RFC: Support for MTE stack tagging.
2025-03-14 13:21 [PATCH 0/2] RFC: Support for MTE stack tagging Cupertino Miranda
2025-03-14 13:21 ` [PATCH 1/2] rtld: Enable MTE for stack when specified in .dynamic Cupertino Miranda
2025-03-14 13:21 ` [PATCH 2/2] nptl: Enable MTE for stacks created for threads Cupertino Miranda
@ 2025-03-14 13:31 ` Cupertino Miranda
2025-03-14 16:33 ` Florian Weimer
3 siblings, 0 replies; 11+ messages in thread
From: Cupertino Miranda @ 2025-03-14 13:31 UTC (permalink / raw)
To: libc-alpha; +Cc: jose.marchesi, elena.zannoni, richard.sandiford, Indu Bhagat
+CC Indu Bhagat <indu.bhagat@oracle.com>
On 14-03-2025 13:21, Cupertino Miranda wrote:
> Hi everyone,
>
> This is an initial work to enable glibc support for MTE stack tagging.
> In a nutshell glibc should set PROT_MTE to any stack pages which get
> allocated for any running application which requires MTE stack tagging.
>
> The approach taken to flag the need for stack tagging is to check
> .dynamic entries specific to aarch64, as described in section 6 from:
> https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst
>
> This is an initial propose patch. I would like to get some feedback
> for the approach used to check for the .dynamic flags, how the
> PROT_MTE property is set for the stacks or any other comments.
>
> This feature is related to the work done by Indu Bhagat submitted as RFC
> in gcc-patches:
> https://gcc.gnu.org/pipermail/gcc-patches/2024-November/668017.html
> And in binutils in:
> https://sourceware.org/pipermail/binutils/2024-December/137989.html
>
> I noticed my patches fail a lot of conform/linknamespace tests. I
> think I need some guidance for why this happens.
>
> Looking forward to your comments.
>
> Best regards,
> Cupertino
>
> Cupertino Miranda (2):
> rtld: Enable MTE for stack when specified in .dynamic.
> nptl: Enable MTE for stacks created for threads.
>
> elf/dl-mte-stack.c | 28 +++++++
> elf/elf.h | 8 +-
> nptl/allocatestack.c | 3 +-
> nptl/nptl-stack.c | 7 ++
> nptl/nptl-stack.h | 2 +
> sysdeps/aarch64/Makefile | 3 +-
> sysdeps/aarch64/cpu-features.h | 15 ++++
> sysdeps/aarch64/dl-mte.c | 50 +++++++++++
> sysdeps/aarch64/dl-prop.h | 4 +
> sysdeps/unix/sysv/linux/aarch64/Makefile | 10 +++
> .../unix/sysv/linux/aarch64/dl-mte-stack.c | 83 +++++++++++++++++++
> 11 files changed, 210 insertions(+), 3 deletions(-)
> create mode 100644 elf/dl-mte-stack.c
> create mode 100644 sysdeps/aarch64/dl-mte.c
> create mode 100644 sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 0/2] RFC: Support for MTE stack tagging.
2025-03-14 13:21 [PATCH 0/2] RFC: Support for MTE stack tagging Cupertino Miranda
` (2 preceding siblings ...)
2025-03-14 13:31 ` [PATCH 0/2] RFC: Support for MTE stack tagging Cupertino Miranda
@ 2025-03-14 16:33 ` Florian Weimer
2025-03-17 13:50 ` Cupertino Miranda
3 siblings, 1 reply; 11+ messages in thread
From: Florian Weimer @ 2025-03-14 16:33 UTC (permalink / raw)
To: Cupertino Miranda
Cc: libc-alpha, jose.marchesi, elena.zannoni, richard.sandiford, Indu Bhagat
* Cupertino Miranda:
> I noticed my patches fail a lot of conform/linknamespace tests. I
> think I need some guidance for why this happens.
That's because you use stack_mem_tagging_prot instead of
__stack_mem_tagging_prot (which is also included in one place). Note
that the .out files should have an indication of the source of the
namespace violation.
Thanks,
Florian
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] nptl: Enable MTE for stacks created for threads.
2025-03-14 13:21 ` [PATCH 2/2] nptl: Enable MTE for stacks created for threads Cupertino Miranda
@ 2025-03-14 16:35 ` Florian Weimer
2025-03-26 17:26 ` Cupertino Miranda
2025-03-19 19:35 ` Adhemerval Zanella Netto
1 sibling, 1 reply; 11+ messages in thread
From: Florian Weimer @ 2025-03-14 16:35 UTC (permalink / raw)
To: Cupertino Miranda
Cc: libc-alpha, jose.marchesi, elena.zannoni, richard.sandiford, Indu Bhagat
* Cupertino Miranda:
> diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
> index 800ca89720..6155157063 100644
> --- a/nptl/allocatestack.c
> +++ b/nptl/allocatestack.c
> @@ -153,7 +153,8 @@ static int allocate_stack_mode = ALLOCATE_GUARD_MADV_GUARD;
> static inline int stack_prot (void)
> {
> return (PROT_READ | PROT_WRITE
> - | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0));
> + | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0)
> + | stack_mem_tagging_prot ());
> }
I think we should clean this up and arrange for the dynamic linker to
determine the PROT_* flags for stacks created at run time, so that we
can use that variable directly without further processing.
Thanks,
Florian
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 0/2] RFC: Support for MTE stack tagging.
2025-03-14 16:33 ` Florian Weimer
@ 2025-03-17 13:50 ` Cupertino Miranda
0 siblings, 0 replies; 11+ messages in thread
From: Cupertino Miranda @ 2025-03-17 13:50 UTC (permalink / raw)
To: Florian Weimer
Cc: libc-alpha, jose.marchesi, elena.zannoni, richard.sandiford, Indu Bhagat
Hi Florian,
Thanks for reviews and help with the linknamespace.
Will prepare a v2 soon.
Cheers,
Cupertino
On 14-03-2025 16:33, Florian Weimer wrote:
> * Cupertino Miranda:
>
>> I noticed my patches fail a lot of conform/linknamespace tests. I
>> think I need some guidance for why this happens.
>
> That's because you use stack_mem_tagging_prot instead of
> __stack_mem_tagging_prot (which is also included in one place). Note
> that the .out files should have an indication of the source of the
> namespace violation.
>
> Thanks,
> Florian
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] rtld: Enable MTE for stack when specified in .dynamic.
2025-03-14 13:21 ` [PATCH 1/2] rtld: Enable MTE for stack when specified in .dynamic Cupertino Miranda
@ 2025-03-19 19:05 ` Adhemerval Zanella Netto
0 siblings, 0 replies; 11+ messages in thread
From: Adhemerval Zanella Netto @ 2025-03-19 19:05 UTC (permalink / raw)
To: Cupertino Miranda, libc-alpha
Cc: jose.marchesi, elena.zannoni, richard.sandiford
On 14/03/25 10:21, Cupertino Miranda wrote:
> MTE stack tagging enabled executables are flagged by setting the dynamic
> array tag DT_AARCH64_MEMTAG_STACK as described in section 6 from:
> https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst
>
> Also the mode in which MTE would react to MTE faults is set by the tag
> DT_AARCH64_MEMTAG_MODE.
>
> This patch verifies for the presence of those tags in the dynamic array
> and performs mprotect on the main application stack map with the extra
> PROT_MTE flag.
>
> ---
> elf/dl-mte-stack.c | 27 +++++++
> elf/elf.h | 8 +-
> sysdeps/aarch64/Makefile | 3 +-
> sysdeps/aarch64/cpu-features.h | 15 ++++
> sysdeps/aarch64/dl-mte.c | 50 +++++++++++++
> sysdeps/aarch64/dl-prop.h | 4 +
> sysdeps/unix/sysv/linux/aarch64/Makefile | 5 ++
> .../unix/sysv/linux/aarch64/dl-mte-stack.c | 74 +++++++++++++++++++
> 8 files changed, 184 insertions(+), 2 deletions(-)
> create mode 100644 elf/dl-mte-stack.c
> create mode 100644 sysdeps/aarch64/dl-mte.c
> create mode 100644 sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c
>
> diff --git a/elf/dl-mte-stack.c b/elf/dl-mte-stack.c
> new file mode 100644
> index 0000000000..f0063b54a0
> --- /dev/null
> +++ b/elf/dl-mte-stack.c
> @@ -0,0 +1,27 @@
> +/* Stack memory tagging support. Stub version.
> + Copyright (C) 2003-2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <ldsodefs.h>
> +#include <errno.h>
> +
> +void
> +_dl_mte_stack_protect (void *stack_end)
> +{
> + return ENOSYS;
> +}
> +rtld_hidden_def (_dl_mte_stack_protect)
I don't think it makes sense now to export the memory tagging support as
a generic ABI, even though this is not really aarch64 specific (RISCV
has Zimte).
The _dl_mte_stack_protect is only called in aarch64 code anyway.
> diff --git a/elf/elf.h b/elf/elf.h
> index 96df2eec01..daf0e52b15 100644
> --- a/elf/elf.h
> +++ b/elf/elf.h
> @@ -1392,6 +1392,7 @@ typedef struct
> #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0)
> #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1)
> #define GNU_PROPERTY_AARCH64_FEATURE_1_GCS (1U << 2)
> +#define GNU_PROPERTY_AARCH64_FEATURE_1_MTE_STACK (1U << 3)
>
> /* The x86 instruction sets indicated by the corresponding bits are
> used in program. Their support in the hardware is optional. */
> @@ -3049,7 +3050,12 @@ enum
> #define DT_AARCH64_BTI_PLT (DT_LOPROC + 1)
> #define DT_AARCH64_PAC_PLT (DT_LOPROC + 3)
> #define DT_AARCH64_VARIANT_PCS (DT_LOPROC + 5)
> -#define DT_AARCH64_NUM 6
> +#define DT_AARCH64_MEMTAG_MODE (DT_LOPROC + 9)
> +#define DT_AARCH64_MEMTAG_HEAP (DT_LOPROC + 11)
> +#define DT_AARCH64_MEMTAG_STACK (DT_LOPROC + 12)
> +#define DT_AARCH64_MEMTAG_GLOBALS (DT_LOPROC + 13)
> +#define DT_AARCH64_MEMTAG_GLOBALSSZ (DT_LOPROC + 15)
> +#define DT_AARCH64_NUM 16
>
> /* AArch64 specific values for the st_other field. */
> #define STO_AARCH64_VARIANT_PCS 0x80
> diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile
> index 4b7f8a5c07..f93ef636ac 100644
> --- a/sysdeps/aarch64/Makefile
> +++ b/sysdeps/aarch64/Makefile
> @@ -11,7 +11,8 @@ endif
> ifeq ($(subdir),elf)
> sysdep-dl-routines += \
> dl-bti \
> - dl-gcs
> + dl-gcs \
> + dl-mte
>
> tests += tst-audit26 \
> tst-audit27
> diff --git a/sysdeps/aarch64/cpu-features.h b/sysdeps/aarch64/cpu-features.h
> index ef4e947e8c..0761549718 100644
> --- a/sysdeps/aarch64/cpu-features.h
> +++ b/sysdeps/aarch64/cpu-features.h
> @@ -66,4 +66,19 @@ struct cpu_features
> bool mops;
> };
>
> +#define ARCH_MTE_MODE_SYNC (1 << 1)
> +#define ARCH_MTE_MODE_ASYNC (1 << 2)
> +#define AARCH64_CPU_FEATURE_MTE_STATE_STACK (1 << 3)
> +
> +#define AARCH64_CPU_FEATURE_MTE_STATE_MODE_MASK (0x3)
> +
> +#define AARCH64_CPU_FEATURE_MTE_STATE_MODE_MASK (0x3)
> +#define AARCH64_CPU_FEATURE_MTE_STATE_MODE_ASYNC (1)
> +#define AARCH64_CPU_FEATURE_MTE_STATE_MODE_SYNC (1 << 1)
> +
> +
> +#ifndef ARCH_INIT_MEMORY_STACK_TAGGING
> +#define ARCH_INIT_MEMORY_STACK_TAGGING _dl_mte_stack_protect
> +#endif
> +
This is not any used anywhere.
> #endif /* _CPU_FEATURES_AARCH64_H */
> diff --git a/sysdeps/aarch64/dl-mte.c b/sysdeps/aarch64/dl-mte.c
> new file mode 100644
> index 0000000000..30740d1eca
> --- /dev/null
> +++ b/sysdeps/aarch64/dl-mte.c
> @@ -0,0 +1,50 @@
> +/* AArch64 MTE Stack functions.
> + Copyright (C) 2020-2025 Free Software Foundation, Inc.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <unistd.h>
> +#include <ldsodefs.h>
> +#include <assert.h>
> +
> +extern void
> +_dl_mte_stack_protect (void *stack_end);
> +
> +void
> +_dl_mte_stack_check (struct link_map *l, const char *program)
> +{
> + /* TODO: Replace the dynamic info by gnu.property entry. */
Not sure what this comment means, is the idea to add GNU_PROPERTY_AARCH64_FEATURE_1_MTE_XXX?
> + ElfW(Dyn) *d;
> + for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
> + {
> + if (d->d_tag == DT_AARCH64_MEMTAG_STACK)
> + GLRO(dl_aarch64_cpu_features).mte_state |= AARCH64_CPU_FEATURE_MTE_STATE_STACK;
> + if (d->d_tag == DT_AARCH64_MEMTAG_MODE)
> + {
> + if (d->d_un.d_val == 1)
> + {
> + GLRO(dl_aarch64_cpu_features).mte_state &= ~AARCH64_CPU_FEATURE_MTE_STATE_MODE_MASK;
> + GLRO(dl_aarch64_cpu_features).mte_state |= AARCH64_CPU_FEATURE_MTE_STATE_MODE_ASYNC;
> + }
> + else
> + {
> + GLRO(dl_aarch64_cpu_features).mte_state &= ~AARCH64_CPU_FEATURE_MTE_STATE_MODE_MASK;
> + GLRO(dl_aarch64_cpu_features).mte_state |= AARCH64_CPU_FEATURE_MTE_STATE_MODE_ASYNC;
Nit: line too long.
> + }
> + }
> + }
> +
> + _dl_mte_stack_protect (__libc_stack_end);
> +}
> diff --git a/sysdeps/aarch64/dl-prop.h b/sysdeps/aarch64/dl-prop.h
> index abca2be7fa..66b05c1b75 100644
> --- a/sysdeps/aarch64/dl-prop.h
> +++ b/sysdeps/aarch64/dl-prop.h
> @@ -27,11 +27,15 @@ extern void _dl_bti_check (struct link_map *, const char *)
> extern void _dl_gcs_check (struct link_map *, const char *)
> attribute_hidden;
>
> +extern void _dl_mte_stack_check (struct link_map *, const char *)
> + attribute_hidden;
> +
> static inline void __attribute__ ((always_inline))
> _rtld_main_check (struct link_map *m, const char *program)
> {
> _dl_bti_check (m, program);
> _dl_gcs_check (m, program);
> + _dl_mte_stack_check (m, program);
> }
>
> static inline void __attribute__ ((always_inline))
> diff --git a/sysdeps/unix/sysv/linux/aarch64/Makefile b/sysdeps/unix/sysv/linux/aarch64/Makefile
> index 1fdad67fae..8fb0e65b2a 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/Makefile
> +++ b/sysdeps/unix/sysv/linux/aarch64/Makefile
> @@ -5,6 +5,11 @@ tests += \
> # tests
> endif
>
> +ifeq ($(subdir),elf)
> +sysdep-dl-routines += \
> + dl-mte-stack
> +endif
> +
> ifeq ($(subdir),stdlib)
> gen-as-const-headers += ucontext_i.sym
> endif
> diff --git a/sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c b/sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c
> new file mode 100644
> index 0000000000..a4bc82c99b
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c
> @@ -0,0 +1,74 @@
> +/* Memory tagging handling for GNU dynamic linker. Stub version.
> + Copyright (C) 2003-2025 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Lesser General Public
> + License as published by the Free Software Foundation; either
> + version 2.1 of the License, or (at your option) any later version.
> +
> + The GNU C Library is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + Lesser General Public License for more details.
> +
> + You should have received a copy of the GNU Lesser General Public
> + License along with the GNU C Library; if not, see
> + <https://www.gnu.org/licenses/>. */
> +
> +#include <ldsodefs.h>
> +#include <libintl.h>
> +#include <not-cancel.h>
> +#include <sys/prctl.h>
> +
> +#define MTE_ALLOWED_TAGS (0xfffe << PR_MTE_TAG_SHIFT)
> +
> +static int
> +_dl_mte_mode (void)
Use bool here.
> +{
> + if (GLRO(dl_aarch64_cpu_features).mte_state & AARCH64_CPU_FEATURE_MTE_STATE_MODE_SYNC)
> + __prctl (PR_SET_TAGGED_ADDR_CTRL,
> + (PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | MTE_ALLOWED_TAGS),
> + 0, 0, 0);
> + else if (GLRO(dl_aarch64_cpu_features).mte_state & AARCH64_CPU_FEATURE_MTE_STATE_MODE_ASYNC)
> + __prctl (PR_SET_TAGGED_ADDR_CTRL,
> + (PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_ASYNC | MTE_ALLOWED_TAGS),
> + 0, 0, 0);
> +
> + return ((GLRO(dl_aarch64_cpu_features).mte_state & AARCH64_CPU_FEATURE_MTE_STATE_MODE_MASK) != 0);
> +}
> +
The MTE mode is already set at init_cpu_features iff USE_MTAG (set by
--enable-memory-tagging) is used. It is not wrong to set it again, but
I would expect that MTE stack support would be also gated by USE_MTAG.
The current MTE support on glibc is enabled by the glibc.mem.tagging
tunable; and the tunable is also the same strategy used by GCS. It is
mainly to enable a better transition once binaries start to use the new
ELF markings. The tunable API also allows us to change it over release,
so we can eventually phase it out in favor of Memtag ABI extension
tagging.
So I think we should use the same strategy here. The GCS supports multiple
values, but essentially it is:
0 = disabled: do not enable GCS.
1 = enforced: check markings and fail if any binary is not marked.
2 = optional: check markings but keep GCS off if any binary is unmarked.
3 = override: enable GCS, markings are ignored.
For DT_AARCH64_MEMTAG_STACK/DT_AARCH64_MEMTAG_HEAP the Memtag ABI extension
says the entry is only valid on the main executable, while
DT_AARCH64_MEMTAG_GLOBALS is defined per shared objects. So I think either
'1' (enforced) or value '2' (optional) are not applicable.
There is an extra issue, where heap support was added prior Memtag ABI
extension. I think we should keep the memory tagging malloc support, but
remove the aarch64 mode to a different tunable.
So I one suggestion would be add a new glibc.cpu.aarch64_mte tunable with
the semantic of:
0 = disable, do not enable MTE even if ELF has the DT_AARCH64_MEMTAG
support. This the default.
1 = enforce, follow the DT_AARCH64_MEMTAG marking of the binary.
2 = override, enable MTE even if there is not DT_AARCH64_MEMTAG where
applicable.
Along with glibc.cpu.aarch64_mte_mode:
0 = async, PR_MTE_TCF_ASYNC.
1 = sync, PR_MTE_TCF_SYNC.
2 = system-preferred faulting mode
The glibc.mem.tagging will be disassociated from the MTE mode (since
it ties aarch64 specific bits to a generic interface), and it would
be just a disable (1) / enable (0) mode.
So to enable heap memory tagging, it would a matter to:
GLIBC_TUNABLE=glibc.cpu.aarch64_mte=2:glibc.mem.tagging=1
The DT_AARCH64_MEMTAG_HEAP should be easier to implement, where is just
acts as glibc.mem.tagging.
It is also confusing that you are reusing the mte_state filed, which is
initialized by the tunable, to also keep track of MTE support. Another
option is move the glibc.mem.tagging to be aarch64 specific anyway
and rename it to glibc.aarc64.mem_tagging or glibc.aarch64.mte_heap.
> +void
> +_dl_mte_stack_protect (void *stack_end)
> +{
> + if ((GLRO(dl_aarch64_cpu_features).mte_state & AARCH64_CPU_FEATURE_MTE_STATE_STACK) == 0
> + || !_dl_mte_mode ())
> + return;
> +
> + int errval = 0;
> + uintptr_t page = ((uintptr_t) stack_end
> + & -(intptr_t) GLRO(dl_pagesize));
> +
> + if (__mprotect ((void *) page, GLRO(dl_pagesize),
> + PROT_READ | PROT_WRITE | PROT_MTE
> + | (GL(dl_stack_flags) & PF_X ? PROT_EXEC : 0)
> +#if _STACK_GROWS_DOWN
> + | PROT_GROWSDOWN
> +#elif _STACK_GROWS_UP
> + | PROT_GROWSUP
> +#endif
> + ) != 0)
> + errval = errno;
> +
> + if (errval)
> + {
> + const char *errstring = NULL;
> + errstring = N_("\
> +cannot set stack with PROT_MTE");
> + const char *name = "MTE Stack";
> + struct dl_exception exception;
> + _dl_exception_create (&exception, name, errstring);
> + _dl_signal_exception (errval, &exception, NULL);
> + }
> +}
> +
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] nptl: Enable MTE for stacks created for threads.
2025-03-14 13:21 ` [PATCH 2/2] nptl: Enable MTE for stacks created for threads Cupertino Miranda
2025-03-14 16:35 ` Florian Weimer
@ 2025-03-19 19:35 ` Adhemerval Zanella Netto
1 sibling, 0 replies; 11+ messages in thread
From: Adhemerval Zanella Netto @ 2025-03-19 19:35 UTC (permalink / raw)
To: Cupertino Miranda, libc-alpha
Cc: jose.marchesi, elena.zannoni, richard.sandiford
On 14/03/25 10:21, Cupertino Miranda wrote:
> This patch adds MPROT_MTE flag to newly mapped stacks for threads, if
> DT_AARCH64_MEMTAG_STACK is present in the array of dynamic tags in the
> executable.
>
> ---
> elf/dl-mte-stack.c | 1 +
> nptl/allocatestack.c | 3 ++-
> nptl/nptl-stack.c | 7 +++++++
> nptl/nptl-stack.h | 2 ++
> sysdeps/unix/sysv/linux/aarch64/Makefile | 5 +++++
> sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c | 11 ++++++++++-
> 6 files changed, 27 insertions(+), 2 deletions(-)
>
> diff --git a/elf/dl-mte-stack.c b/elf/dl-mte-stack.c
> index f0063b54a0..f5b8293c7a 100644
> --- a/elf/dl-mte-stack.c
> +++ b/elf/dl-mte-stack.c
> @@ -25,3 +25,4 @@ _dl_mte_stack_protect (void *stack_end)
> return ENOSYS;
> }
> rtld_hidden_def (_dl_mte_stack_protect)
> +
> diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
> index 800ca89720..6155157063 100644
> --- a/nptl/allocatestack.c
> +++ b/nptl/allocatestack.c
> @@ -153,7 +153,8 @@ static int allocate_stack_mode = ALLOCATE_GUARD_MADV_GUARD;
> static inline int stack_prot (void)
> {
> return (PROT_READ | PROT_WRITE
> - | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0));
> + | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0)
> + | stack_mem_tagging_prot ());
> }
>
> static void *
> diff --git a/nptl/nptl-stack.c b/nptl/nptl-stack.c
> index c049c5133c..34fbba1cd1 100644
> --- a/nptl/nptl-stack.c
> +++ b/nptl/nptl-stack.c
> @@ -145,3 +145,10 @@ __pthread_get_minstack (const pthread_attr_t *attr)
> + PTHREAD_STACK_MIN);
> }
> libc_hidden_def (__pthread_get_minstack)
> +
> +int
> +__stack_mem_tagging_prot (void)
> +{
> + return 0;
> +}
> +weak_alias (__stack_mem_tagging_prot, stack_mem_tagging_prot)
As indicated, this causas the linknamespace issues because stack_mem_tagging_prot
is in the application namespace.
> diff --git a/nptl/nptl-stack.h b/nptl/nptl-stack.h
> index ac672e16cf..2bfcaf7252 100644
> --- a/nptl/nptl-stack.h
> +++ b/nptl/nptl-stack.h
> @@ -61,4 +61,6 @@ __nptl_tls_static_size_for_stack (void)
> return roundup (GLRO (dl_tls_static_size), GLRO (dl_tls_static_align));
> }
>
> +int stack_mem_tagging_prot (void);
> +
> #endif /* _NPTL_STACK_H */
> diff --git a/sysdeps/unix/sysv/linux/aarch64/Makefile b/sysdeps/unix/sysv/linux/aarch64/Makefile
> index 8fb0e65b2a..e91a756836 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/Makefile
> +++ b/sysdeps/unix/sysv/linux/aarch64/Makefile
> @@ -10,6 +10,11 @@ sysdep-dl-routines += \
> dl-mte-stack
> endif
>
> +ifeq ($(subdir),nptl)
> +routines += \
> + dl-mte-stack
> +endif
> +
This add a static linking issue (link-static-libc test) with multiple
definition of _dl_mte_stack_protect and stack_mem_tagging_prot.
And I don't think you need to set the MTE mode per thread, once the
mode it sets either by the tunable of by DT_AARCH64_MEMTAG_MODE it
should not be changed by glibc.
I also think it should be done with Florian's suggestion, so there
is no need to add teh __stack_mem_tagging_prot hook and override it
on aarch64.
Now that we don't change dl_stack_flags during process execution,
we can more to the _rtld_global_ro and setup the mmap flags after
loader setup instead of the ELF ones.
> ifeq ($(subdir),stdlib)
> gen-as-const-headers += ucontext_i.sym
> endif
> diff --git a/sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c b/sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c
> index a4bc82c99b..7ed92855ae 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c
> +++ b/sysdeps/unix/sysv/linux/aarch64/dl-mte-stack.c
> @@ -42,7 +42,7 @@ void
> _dl_mte_stack_protect (void *stack_end)
> {
> if ((GLRO(dl_aarch64_cpu_features).mte_state & AARCH64_CPU_FEATURE_MTE_STATE_STACK) == 0
> - || !_dl_mte_mode ())
> + || !_dl_mte_mode ())
> return;
>
> int errval = 0;
> @@ -72,3 +72,12 @@ cannot set stack with PROT_MTE");
> }
> }
>
> +int
> +stack_mem_tagging_prot (void)
> +{
> + if ((GLRO(dl_aarch64_cpu_features).mte_state & AARCH64_CPU_FEATURE_MTE_STATE_STACK) == 8
> + && _dl_mte_mode ())
> + return PROT_MTE;
> + else
> + return 0;
> +}
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] nptl: Enable MTE for stacks created for threads.
2025-03-14 16:35 ` Florian Weimer
@ 2025-03-26 17:26 ` Cupertino Miranda
2025-03-26 18:44 ` Florian Weimer
0 siblings, 1 reply; 11+ messages in thread
From: Cupertino Miranda @ 2025-03-26 17:26 UTC (permalink / raw)
To: Florian Weimer
Cc: libc-alpha, jose.marchesi, elena.zannoni, richard.sandiford, Indu Bhagat
Hi Florian,
Thanks for the review!
On 14-03-2025 16:35, Florian Weimer wrote:
> * Cupertino Miranda:
>
>> diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
>> index 800ca89720..6155157063 100644
>> --- a/nptl/allocatestack.c
>> +++ b/nptl/allocatestack.c
>> @@ -153,7 +153,8 @@ static int allocate_stack_mode = ALLOCATE_GUARD_MADV_GUARD;
>> static inline int stack_prot (void)
>> {
>> return (PROT_READ | PROT_WRITE
>> - | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0));
>> + | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0)
>> + | stack_mem_tagging_prot ());
>> }
>
> I think we should clean this up and arrange for the dynamic linker to
> determine the PROT_* flags for stacks created at run time, so that we
> can use that variable directly without further processing.
IMHO, we cannot escape from abstracting somehow the final flags as above
with PF_X.
The problem being that each OS would have each own flags and syscalls
and dynamic linker is OS agnostic, AFAIK.
Were you suggesting to create a PF_MTE and abstract it that way ?
Or having dl_stack_flags to immediately be set to PROT_MTE, etc?
Thanks,
Cupertino
>
> Thanks,
> Florian
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] nptl: Enable MTE for stacks created for threads.
2025-03-26 17:26 ` Cupertino Miranda
@ 2025-03-26 18:44 ` Florian Weimer
0 siblings, 0 replies; 11+ messages in thread
From: Florian Weimer @ 2025-03-26 18:44 UTC (permalink / raw)
To: Cupertino Miranda
Cc: libc-alpha, jose.marchesi, elena.zannoni, richard.sandiford, Indu Bhagat
* Cupertino Miranda:
> Hi Florian,
>
> Thanks for the review!
>
> On 14-03-2025 16:35, Florian Weimer wrote:
>> * Cupertino Miranda:
>>
>>> diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
>>> index 800ca89720..6155157063 100644
>>> --- a/nptl/allocatestack.c
>>> +++ b/nptl/allocatestack.c
>>> @@ -153,7 +153,8 @@ static int allocate_stack_mode = ALLOCATE_GUARD_MADV_GUARD;
>>> static inline int stack_prot (void)
>>> {
>>> return (PROT_READ | PROT_WRITE
>>> - | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0));
>>> + | ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0)
>>> + | stack_mem_tagging_prot ());
>>> }
>> I think we should clean this up and arrange for the dynamic linker to
>> determine the PROT_* flags for stacks created at run time, so that we
>> can use that variable directly without further processing.
> IMHO, we cannot escape from abstracting somehow the final flags as
> above with PF_X. The problem being that each OS would have each own
> flags and syscalls and dynamic linker is OS agnostic, AFAIK.
The dynamic linker has both Linux- and architecture-specific code.
I would like to see
GLRO (dl_stack_prot_flags)
instead of:
stack_prot ()
Then we can remove the GL(dl_stack_flags) variable.
Thanks,
Florian
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-03-26 18:44 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-14 13:21 [PATCH 0/2] RFC: Support for MTE stack tagging Cupertino Miranda
2025-03-14 13:21 ` [PATCH 1/2] rtld: Enable MTE for stack when specified in .dynamic Cupertino Miranda
2025-03-19 19:05 ` Adhemerval Zanella Netto
2025-03-14 13:21 ` [PATCH 2/2] nptl: Enable MTE for stacks created for threads Cupertino Miranda
2025-03-14 16:35 ` Florian Weimer
2025-03-26 17:26 ` Cupertino Miranda
2025-03-26 18:44 ` Florian Weimer
2025-03-19 19:35 ` Adhemerval Zanella Netto
2025-03-14 13:31 ` [PATCH 0/2] RFC: Support for MTE stack tagging Cupertino Miranda
2025-03-14 16:33 ` Florian Weimer
2025-03-17 13:50 ` Cupertino Miranda
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).