[glibc/azanella/aarch64-memtag] aarch64: Add support for DT_AARCH64_MEMTAG_HEAP with USE_MTAG
Adhemerval Zanella via Glibc-cvs <[email protected]>
| Newsgroups | gmane.comp.lib.glibc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=fcadc6dacc3e22cfdb14a98faa03a001e9d8d7a5 commit fcadc6dacc3e22cfdb14a98faa03a001e9d8d7a5 Author: Adhemerval Zanella <[email protected]> Date: Wed Apr 1 17:39:15 2026 -0300 aarch64: Add support for DT_AARCH64_MEMTAG_HEAP with USE_MTAG This patch extends the AArch64 Memtag ABI Extension support in the dynamic linker by processing the DT_AARCH64_MEMTAG_HEAP dynamic tag. This tag enables Memory Tagging Extension (MTE) protections for the libc heap allocator. The DT_AARCH64_MEMTAG_HEAP is only honored if glibc is configured with --enable-memory-tagging (USE_MTAG). If the ELF tag requests heap tagging but glibc lacks USE_MTAG support, the dynamic linker will emit a fatal error. The glibc.mem.tagging tunable behavior is updated to correctly mask or enable MTE_HEAP, and similar to stack tagging the tunable has precedence over the dynamic tag. If a shared object requiring MTE heap tagging is loaded via `dlopen` it will fail safely with an error if MTE support was not initialized at process startup. The patch adds a configure-time check to verify if the linker supports the '-z memtag-heap' option (it is used to enable the heap tests); Diff: --- INSTALL | 14 ++--- NEWS | 7 ++- manual/install.texi | 25 ++++---- sysdeps/aarch64/configure | 37 ++++++++++++ sysdeps/aarch64/configure.ac | 7 +++ sysdeps/aarch64/dl-mte.c | 57 ++++++++++++------ sysdeps/unix/sysv/linux/aarch64/Makefile | 51 +++++++++++++++- .../linux/aarch64/tst-memtag-dlopen-skeleton.c | 48 +++++++++++++++ .../sysv/linux/aarch64/tst-memtag-heap-async.c | 1 + .../sysv/linux/aarch64/tst-memtag-heap-disable.c | 38 ++++++++++++ .../sysv/linux/aarch64/tst-memtag-heap-dlopen.c | 3 + .../sysv/linux/aarch64/tst-memtag-heap-skeleton.c | 70 ++++++++++++++++++++++ .../unix/sysv/linux/aarch64/tst-memtag-heap-sync.c | 1 + sysdeps/unix/sysv/linux/aarch64/tst-memtag-mod3.c | 1 + .../sysv/linux/aarch64/tst-memtag-stack-dlopen.c | 48 +-------------- .../sysv/linux/aarch64/tst-memtag-test-skeleton.c | 20 +------ 16 files changed, 324 insertions(+), 104 deletions(-) diff --git a/INSTALL b/INSTALL index 2c264c0b96..0a53ffabc9 100644 --- a/INSTALL +++ b/INSTALL @@ -301,15 +301,15 @@ passed to 'configure'. For example: '--enable-aarch64-memtag-abi' Enable initial support for the AArch64 Memory Tagging Extension (MTE) ABI. - The option implements stack tagging (DT_AARCH64_MEMTAG_STACK) and MTE - execution mode configuration (DT_AARCH64_MEMTAG_MODE) as defined in the - Memtag ABI Extension for ELF64. + The option implements stack tagging (DT_AARCH64_MEMTAG_STACK), MTE + execution mode configuration (DT_AARCH64_MEMTAG_MODE), and heap tagging + (DT_AARCH64_MEMTAG_HEAP) as defined in the Memtag ABI Extension for ELF64. - Unsupported options (DT_AARCH64_MEMTAG_HEAP and DT_AARCH64_MEMTAG_GLOBALS) - triggers either startup failure or dlopen errors. + Unsupported options (DT_AARCH64_MEMTAG_GLOBALS) triggers either startup + failure or dlopen errors. - If `--enable-memory-tagging` is also uses, the `glibc.mem.tagging` tunable - takes precedence. + The heap tagging requires `--enable-memory-tagging`, and the + `glibc.mem.tagging` tunable takes precedence. This option is disabled by default and only support on aarch64. diff --git a/NEWS b/NEWS index ea9fc1af1f..228b3512d5 100644 --- a/NEWS +++ b/NEWS @@ -17,9 +17,10 @@ Major new features: improvements in performance. * On AArch64 now has initial support for the Memtag ABI Extension for ELF64, - specifically handling stack tagging (DT_AARCH64_MEMTAG_STACK) and execution - mode configuration (DT_AARCH64_MEMTAG_MODE). This can be enabled using thw - new --enable-aarch64-memtag-abi configure option. + specifically handling stack tagging (DT_AARCH64_MEMTAG_STACK), execution + mode configuration (DT_AARCH64_MEMTAG_MODE), and head tagging + (DT_AARCH64_MEMTAG_HEAP). This can be enabled using thw new + --enable-aarch64-memtag-abi configure option. Deprecated and removed features, and other changes affecting compatibility: diff --git a/manual/install.texi b/manual/install.texi index 99a0023664..32110d855f 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -331,18 +331,19 @@ Default is to disable SFrame support. @item --enable-aarch64-memtag-abi Enable initial support for the AArch64 Memory Tagging Extension (MTE) ABI. -The option implements stack tagging (DT_AARCH64_MEMTAG_STACK) and MTE -execution mode configuration (DT_AARCH64_MEMTAG_MODE) as defined in the -Memtag ABI Extension for ELF64. - -Unsupported options (DT_AARCH64_MEMTAG_HEAP and DT_AARCH64_MEMTAG_GLOBALS) -triggers either startup failure or dlopen errors. If the execution mode -is not specified, the system defaults to asynchronous mode. - -If @option{--enable-memory-tagging} is also uses, the @code{glibc.mem.tagging} -tunable takes precedence. The tunable can override the MTE mode requested by -the MEMTAG ABI (e.g., forcing synchronous mode or deferring to the -system-preferred auto mode) and can independently enable heap tagging. +The option implements stack tagging (DT_AARCH64_MEMTAG_STACK), MTE +execution mode configuration (DT_AARCH64_MEMTAG_MODE), and heap tagging +(DT_AARCH64_MEMTAG_HEAP) as defined in the Memtag ABI Extension for ELF64. + +Unsupported options (DT_AARCH64_MEMTAG_GLOBALS) triggers either startup +failure or dlopen errors. If the execution mode is not specified, the +system defaults to asynchronous mode. + +The heap tagging requires @option{--enable-memory-tagging}, and the +@code{glibc.mem.tagging} tunable takes precedence. The tunable can +override the MTE mode requested by the MEMTAG ABI (e.g., forcing +synchronous mode or deferring to the system-preferred auto mode) and +can independently enable heap tagging. If the main executable does not enable the MTE stack at startup, any subsequent attempts to @code{dlopen} a shared object that requires MTE diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure index 8577ee69a7..02be02da43 100755 --- a/sysdeps/aarch64/configure +++ b/sysdeps/aarch64/configure @@ -587,3 +587,40 @@ else have-test-memtag-stack = no" fi +# Check if linker supports Memtag Heap support +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker that supports -z memtag-heap" >&5 +printf %s "checking for linker that supports -z memtag-heap... " >&6; } +libc_linker_feature=no +cat > conftest.c <<EOF +int _start (void) { return 42; } +EOF +if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp + -Wl,--fatal-warnings -Wl,-z,memtag-heap -nostdlib -nostartfiles + -fPIC -shared -o conftest.so conftest.c + 1>&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } +then + if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -Wl,--fatal-warnings -Wl,-z,memtag-heap -nostdlib \ + -nostartfiles -fPIC -shared -o conftest.so conftest.c 2>&1 \ + | grep "warning: -z memtag-heap ignored" > /dev/null 2>&1; then + true + else + libc_linker_feature=yes + fi +fi +rm -f conftest* +if test $libc_linker_feature = yes; then + libc_cv_ld_memtag_heap=yes +else + libc_cv_ld_memtag_heap=no + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5 +printf "%s\n" "$libc_linker_feature" >&6; } +config_vars="$config_vars +have-test-memtag-heap = $libc_cv_ld_memtag_heap" + diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac index 7d6e8c0815..38de7642cd 100644 --- a/sysdeps/aarch64/configure.ac +++ b/sysdeps/aarch64/configure.ac @@ -130,3 +130,10 @@ then else LIBC_CONFIG_VAR([have-test-memtag-stack], [no]) fi + +# Check if linker supports Memtag Heap support +LIBC_LINKER_FEATURE( + [-z memtag-heap], [-Wl,--fatal-warnings -Wl,-z,memtag-heap], + [libc_cv_ld_memtag_heap=yes], [libc_cv_ld_memtag_heap=no] +) +LIBC_CONFIG_VAR([have-test-memtag-heap], [$libc_cv_ld_memtag_heap]) diff --git a/sysdeps/aarch64/dl-mte.c b/sysdeps/aarch64/dl-mte.c index cb8ec64d88..fbfa83e49c 100644 --- a/sysdeps/aarch64/dl-mte.c +++ b/sysdeps/aarch64/dl-mte.c @@ -32,22 +32,39 @@ # define DT_AARCH64(x) (DT_AARCH64_##x - DT_LOPROC + DT_NUM) +typedef enum +{ + MTE_ERROR_SUPPORT, + MTE_ERROR_STACK, + MTE_ERROR_HEAP, + MTE_ERROR_GLOBALS, +} mte_error_mode; + static void -fail (const struct link_map *l, const char *program, const char *mode) +fail (const struct link_map *l, const char *program, mte_error_mode mode) { if (program != NULL) { + const char *modestr; + switch (mode) + { + case MTE_ERROR_STACK: modestr = "stack"; break; + case MTE_ERROR_HEAP: modestr = "heap"; break; + case MTE_ERROR_GLOBALS: modestr = "global"; break; + default: __builtin_unreachable (); + } + if (program[0] != '\0' && l->l_name[0] != '\0') - _dl_fatal_printf ("%s: %s: MTE protection %s is not supported\n", - program, l->l_name, mode); + _dl_fatal_printf ("%s: %s: MTE %s protection is not supported\n", + program, l->l_name, modestr); if (program[0] != '\0') - _dl_fatal_printf ("%s: MTE protection %s is not supported\n", - program, mode); - _dl_fatal_printf ("error: MTE protection %s is not supported\n", - mode); + _dl_fatal_printf ("%s: MTE %s protection is not supported\n", + program, modestr); + _dl_fatal_printf ("error: MTE %s protection is not supported\n", + modestr); } else - _dl_signal_error (0, l->l_name, "dlopen", "MTE is not enabled"); + _dl_signal_error (0, l->l_name, "dlopen", "MTE support is not enabled"); } static void @@ -111,9 +128,13 @@ static void check_mte (const struct link_map *l, const char *program) if (requires_mte_stack (l)) GL(dl_aarch64_mte) |= MTE_STACK; if (requires_mte_heap (l)) - fail (l, program, "heap"); +# ifdef USE_MTAG + GL(dl_aarch64_mte) |= MTE_HEAP; +# else + fail (l, program, MTE_ERROR_HEAP); +# endif if (requires_mte_globals (l)) - fail (l, program, "globals"); + fail (l, program, MTE_ERROR_GLOBALS); } #endif @@ -133,8 +154,8 @@ static inline bool enable_mte_stack (void) static inline bool enable_mte_heap (void) { -#ifdef USE_MTAB - return GL(dl_aarch64_mte) & MTE_HEAD; +#if defined USE_MTAB || defined USE_AARCH64_MEMTAG_ABI + return GL(dl_aarch64_mte) & MTE_HEAP; #else return false; #endif @@ -155,13 +176,13 @@ _dl_mte_check (struct link_map *l, const char *program) for (unsigned int i = 0; i < l->l_searchlist.r_nlist; i++) check_mte (l->l_searchlist.r_list[i], program); - /* For dlopen, if program has not enabled MTE stack at the startup, signal - that the module can not be loaded. */ - if (enable_mte_stack () && program == NULL) + /* For dlopen, if program has not enabled MTE at the startup, signal that + the module can not be loaded. */ + if ((enable_mte_stack () || enable_mte_heap()) && program == NULL) { - GL(dl_aarch64_mte) &= ~MTE_STACK; + GL(dl_aarch64_mte) &= ~(MTE_STACK | MTE_HEAP); - fail (l, program, "stack"); + fail (l, program, MTE_ERROR_SUPPORT); } #endif } @@ -188,6 +209,8 @@ _dl_mte_init (void) NULL); if (mte_tunable & 0x1) GL(dl_aarch64_mte) |= MTE_HEAP; + else + GL(dl_aarch64_mte) &= ~MTE_HEAP; if (mte_tunable & 0x2) { GL(dl_aarch64_mte) &= ~MTE_MODE_ASYNC; diff --git a/sysdeps/unix/sysv/linux/aarch64/Makefile b/sysdeps/unix/sysv/linux/aarch64/Makefile index 1a686e3994..e928f5b90b 100644 --- a/sysdeps/unix/sysv/linux/aarch64/Makefile +++ b/sysdeps/unix/sysv/linux/aarch64/Makefile @@ -381,10 +381,26 @@ tests-special += \ $(objpfx)tst-memtag-stack-sync-tunable.out \ # tests-special +ifeq ($(have-test-memtag-heap),yes) +tests += \ + tst-memtag-heap-async \ + tst-memtag-heap-disable \ + tst-memtag-heap-dlopen \ + tst-memtag-heap-sync \ + # tests + +tests-special += \ + $(objpfx)tst-memtag-heap-sync.out \ + $(objpfx)tst-memtag-heap-async.out \ + $(objpfx)tst-memtag-heap-disable.out \ + # tests +endif + modules-names += \ tst-memtag-mod1 \ tst-memtag-mod2 \ - # modules-names + tst-memtag-mod3 \ + # modules-names # Disable stack protector for stack tagging tests. Some GCC versions have a # a bug where the stack frame untagging at the function epiloge is done before @@ -419,6 +435,39 @@ $(objpfx)tst-memtag-stack-sync-tunable.out: $(objpfx)tst-memtag-stack-async $(test-program-cmd-after-env) sync $< \ > $@ 2>&1; echo "status: $$?" >> $@; \ $(evaluate-test) + +LDFLAGS-tst-memtag-heap-sync += -Wl,-z,memtag-heap -Wl,-z,memtag-mode=sync +$(objpfx)tst-memtag-heap-sync.out: $(objpfx)tst-memtag-heap-sync + $(test-program-cmd-before-env) \ + $(run-program-env) \ + $(test-program-cmd-after-env) $< \ + > $@ 2>&1; echo "status: $$?" >> $@; \ + grep -q 'MTE heap protection is not supported' $@ \ + || grep -q '^status: 79$$' $@; \ + $(evaluate-test) + +CFLAGS-tst-memtag-heap-async.c += -DMEMTAG_MODE_ASYNC +LDFLAGS-tst-memtag-heap-async += -Wl,-z,memtag-heap -Wl,-z,memtag-mode=async +$(objpfx)tst-memtag-heap-async.out: $(objpfx)tst-memtag-heap-async + $(test-program-cmd-before-env) \ + $(run-program-env) \ + $(test-program-cmd-after-env) $< \ + > $@ 2>&1; echo "status: $$?" >> $@; \ + grep -q 'MTE heap protection is not supported' $@ \ + || grep -q '^status: 79$$' $@; \ + $(evaluate-test) + +$(objpfx)tst-memtag-heap-dlopen.out: $(objpfx)tst-memtag-mod3.so +LDFLAGS-tst-memtag-mod3.so += -Wl,-z,memtag-heap + +LDFLAGS-tst-memtag-heap-disable += -Wl,-z,memtag-heap +$(objpfx)tst-memtag-heap-disable.out: $(objpfx)tst-memtag-heap-disable + $(test-program-cmd-before-env) \ + $(run-program-env) \ + GLIBC_TUNABLES=glibc.mem.tagging=0 \ + $(test-program-cmd-after-env) $< \ + > $@ 2>&1; echo "status: $$?" >> $@; \ + $(evaluate-test) endif # ifeq ($(aarch64-memtag-abi)$(have-test-memtag-stack),yesyes) endif # ifeq ($(subdir),misc) diff --git a/sysdeps/unix/sysv/linux/aarch64/tst-memtag-dlopen-skeleton.c b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-dlopen-skeleton.c new file mode 100644 index 0000000000..161cca911b --- /dev/null +++ b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-dlopen-skeleton.c @@ -0,0 +1,48 @@ +/* Tests for MEMTAG dleopn support. + Copyright (C) 2026 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 <stdio.h> +#include <dlfcn.h> +#include <string.h> +#include <sys/auxv.h> +#include <support/check.h> + +#include "tst-mte-helper.h" + +static int +do_test (void) +{ + /* Not strickly required to check for MTE capability. */ + if (!(getauxval (AT_HWCAP2) & HWCAP2_MTE)) + FAIL_UNSUPPORTED ("kernel or CPU does not support or enable MTE"); + + TEST_VERIFY_EXIT (!mte_enable ()); + + /* Verify that if MTE is not enabled at startup, trying to load a DSO that + requires MTE should fail. */ + void *h = dlopen (MEMTAG_MOD_NAME, RTLD_NOW); + TEST_VERIFY (h == NULL); + const char *message = dlerror (); + printf ("debug: %s\n", message); + if (strstr (message, DLERROR_MSG) == 0) + FAIL_EXIT1 ("invalid dlopen error message"); + + return 0; +} + +#include <support/test-driver.c> diff --git a/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-async.c b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-async.c new file mode 100644 index 0000000000..23059dbb2b --- /dev/null +++ b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-async.c @@ -0,0 +1 @@ +#include "tst-memtag-heap-skeleton.c" diff --git a/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-disable.c b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-disable.c new file mode 100644 index 0000000000..e58e9d1cf4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-disable.c @@ -0,0 +1,38 @@ +/* Tests for MEMTAG heap support. + Copyright (C) 2026 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 <libc-diag.h> +#include <sys/auxv.h> + +#include <support/check.h> +#include <support/support.h> + +#include "tst-mte-helper.h" + +static int +do_test (void) +{ + if (!(getauxval (AT_HWCAP2) & HWCAP2_MTE)) + FAIL_UNSUPPORTED ("kernel or CPU does not support or enable MTE"); + + TEST_VERIFY_EXIT (!mte_enable ()); + + return 0; +} + +#include <support/test-driver.c> diff --git a/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-dlopen.c b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-dlopen.c new file mode 100644 index 0000000000..a705c55250 --- /dev/null +++ b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-dlopen.c @@ -0,0 +1,3 @@ +#define MEMTAG_MOD_NAME "tst-memtag-mod3.so" +#define DLERROR_MSG "MTE support is not enabled" +#include "tst-memtag-dlopen-skeleton.c" diff --git a/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-skeleton.c b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-skeleton.c new file mode 100644 index 0000000000..ab8753e877 --- /dev/null +++ b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-skeleton.c @@ -0,0 +1,70 @@ +/* Tests for MEMTAG heap support. + Copyright (C) 2026 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 <libc-diag.h> +#include <sys/auxv.h> + +#include <support/check.h> +#include <support/xthread.h> +#include <support/xsignal.h> +#include <support/support.h> + +#include "tst-mte-helper.h" + +static void +__attribute_noinline__ +__attribute_optimization_barrier__ +trigger_mte_fault (void) +{ + DIAG_PUSH_NEEDS_COMMENT; + DIAG_IGNORE_NEEDS_COMMENT_GCC (16, "-Warray-bounds"); + + sigset_t mask; + sigemptyset (&mask); + sigaddset (&mask, SIGSEGV); + + volatile char *ptr = xmalloc (MTE_GRANULE_SIZE); + /* Access memory strictly outside the allocated chunk. Adding + MTE_GRANULE_SIZE bytes pushes us into the next granule, which + will have a different tag. */ + ptr[16] = 0xFF; +} + +static int +do_test (void) +{ + if (!(getauxval (AT_HWCAP2) & HWCAP2_MTE)) + FAIL_UNSUPPORTED ("kernel or CPU does not support or enable MTE"); + + TEST_VERIFY_EXIT (mte_enable ()); + TEST_VERIFY_EXIT (mte_mode () == +#ifdef MEMTAG_MODE_ASYNC + PR_MTE_TCF_ASYNC +#else + PR_MTE_TCF_SYNC +#endif + ); + + install_sigsegv_handler (); + + trigger_mte_fault (); + + return 0; +} + +#include <support/test-driver.c> diff --git a/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-sync.c b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-sync.c new file mode 100644 index 0000000000..23059dbb2b --- /dev/null +++ b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-heap-sync.c @@ -0,0 +1 @@ +#include "tst-memtag-heap-skeleton.c" diff --git a/sysdeps/unix/sysv/linux/aarch64/tst-memtag-mod3.c b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-mod3.c new file mode 100644 index 0000000000..07f2a2d7ba --- /dev/null +++ b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-mod3.c @@ -0,0 +1 @@ +int foo (void) { return 0; } diff --git a/sysdeps/unix/sysv/linux/aarch64/tst-memtag-stack-dlopen.c b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-stack-dlopen.c index ad103356e9..bc4c26191a 100644 --- a/sysdeps/unix/sysv/linux/aarch64/tst-memtag-stack-dlopen.c +++ b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-stack-dlopen.c @@ -1,45 +1,3 @@ -/* Tests for MEMTAG support. - Copyright (C) 2026 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 <dlfcn.h> -#include <string.h> -#include <sys/auxv.h> -#include <support/check.h> - -#include "tst-mte-helper.h" - -static int -do_test (void) -{ - if (!(getauxval (AT_HWCAP2) & HWCAP2_MTE)) - FAIL_UNSUPPORTED ("kernel or CPU does not support or enable MTE"); - - TEST_VERIFY_EXIT (!mte_enable ()); - - /* Verify that if MTE is not enabled at startup, trying to load a DSO that - requires MTE should fail. */ - void *h = dlopen ("tst-memtag-mod2.so", RTLD_NOW); - TEST_VERIFY (h == NULL); - const char *message = dlerror (); - if (strstr (message, "MTE is not enabled") == 0) - FAIL_EXIT1 ("invalid dlopen error message"); - - return 0; -} - -#include <support/test-driver.c> +#define MEMTAG_MOD_NAME "tst-memtag-mod2.so" +#define DLERROR_MSG "MTE support is not enabled" +#include "tst-memtag-dlopen-skeleton.c" diff --git a/sysdeps/unix/sysv/linux/aarch64/tst-memtag-test-skeleton.c b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-test-skeleton.c index 52e4f9fc31..29192b305f 100644 --- a/sysdeps/unix/sysv/linux/aarch64/tst-memtag-test-skeleton.c +++ b/sysdeps/unix/sysv/linux/aarch64/tst-memtag-test-skeleton.c @@ -19,22 +19,11 @@ #include <stdlib.h> #include <libc-diag.h> #include <support/check.h> -#include <support/xsignal.h> #include <support/xthread.h> #include <unistd.h> #include "tst-mte-helper.h" -static void -sigsegv_handler (int signum, siginfo_t *si, void *context) -{ - if (si->si_signo == SIGSEGV - && (si->si_code == SEGV_MTESERR || si->si_code == SEGV_MTEAERR)) - _exit (EXIT_MTESERR); - else - _exit (EXIT_FAILURE); -} - /* Prevent inlining so the stack frame is definitively constructed to trigger a stack frame, and optimization to avoid compiler optimize away the invalid stack operation. */ @@ -64,14 +53,7 @@ run_mte_test (void *closure) { test_mode mode = (test_mode)(uintptr_t)closure; - { - struct sigaction sa = { - .sa_sigaction = sigsegv_handler, - .sa_flags = SA_NODEFER | SA_SIGINFO, - }; - sigemptyset (&sa.sa_mask); - xsigaction (SIGSEGV, &sa, NULL); - } + install_sigsegv_handler (); if (mode == TEST_MAIN) trigger_mte_fault (NULL);