[PATCH 2/4] aarch64: Add LD_AUDIT tests for BTI handling
Adhemerval Zanella
adhemerval.zanella@linaro.org
Tue Jan 6 20:00:58 GMT 2026
This patch adds 3 new tests:
1. tst-bti-permissive-audit: checks that process runs when an LD_AUDIT module
s not marked with BTI but BTI is not enforced.
2. tst-bti-prot-audit: heck if the process correctly handles audit module with
BTI marking when BTI is enforced.
3. tst-bti-unprot-audit: check if the process ignores and audit module without
BTI marking when BTI is enforced.
Checked on aarch64-linux-gnu with Linux 6.18 on Apple M4 emulated (for
BTI support) and on qemu 10.1.50 simulated (for GCS).
---
sysdeps/aarch64/Makefile | 18 +++++
sysdeps/aarch64/tst-bti-mod-audit-skeleton.c | 47 ++++++++++++
sysdeps/aarch64/tst-bti-mod-prot-audit.c | 1 +
sysdeps/aarch64/tst-bti-mod-unprot-audit.c | 1 +
sysdeps/aarch64/tst-bti-permissive-audit.c | 9 +++
sysdeps/aarch64/tst-bti-prot-audit.c | 9 +++
sysdeps/aarch64/tst-bti-skeleton-audit.c | 80 ++++++++++++++++++++
sysdeps/aarch64/tst-bti-unprot-audit.c | 13 ++++
8 files changed, 178 insertions(+)
create mode 100644 sysdeps/aarch64/tst-bti-mod-audit-skeleton.c
create mode 100644 sysdeps/aarch64/tst-bti-mod-prot-audit.c
create mode 100644 sysdeps/aarch64/tst-bti-mod-unprot-audit.c
create mode 100644 sysdeps/aarch64/tst-bti-permissive-audit.c
create mode 100644 sysdeps/aarch64/tst-bti-prot-audit.c
create mode 100644 sysdeps/aarch64/tst-bti-skeleton-audit.c
create mode 100644 sysdeps/aarch64/tst-bti-unprot-audit.c
diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile
index e2c6dbd89d..90a8036d52 100644
--- a/sysdeps/aarch64/Makefile
+++ b/sysdeps/aarch64/Makefile
@@ -98,17 +98,22 @@ tests += \
tst-bti-dlopen-imm \
tst-bti-dlopen-prot \
tst-bti-dlopen-transitive \
+ tst-bti-permissive-audit \
tst-bti-permissive-dlopen \
tst-bti-permissive-imm \
tst-bti-permissive-preload \
tst-bti-permissive-transitive \
+ tst-bti-prot-audit \
+ tst-bti-unprot-audit \
# tests
modules-names += \
tst-bti-mod \
tst-bti-mod-prot \
+ tst-bti-mod-prot-audit \
tst-bti-mod-prot-preload \
tst-bti-mod-unprot \
+ tst-bti-mod-unprot-audit \
tst-bti-mod-unprot-preload \
# modules-names
@@ -140,6 +145,7 @@ tst-bti-permissive-preload-ENV = \
CFLAGS-tst-bti-abort-unprot.o += -mbranch-protection=none
CFLAGS-tst-bti-mod-unprot.os += -mbranch-protection=none
CFLAGS-tst-bti-mod-unprot-preload.os += -mbranch-protection=none
+CFLAGS-tst-bti-mod-unprot-audit.os += -mbranch-protection=none
tst-bti-abort-imm-ENV = GLIBC_TUNABLES=glibc.cpu.aarch64_bti=1
tst-bti-abort-transitive-ENV = GLIBC_TUNABLES=glibc.cpu.aarch64_bti=1
@@ -153,6 +159,18 @@ tst-bti-permissive-imm-ENV = GLIBC_TUNABLES=glibc.cpu.aarch64_bti=0
tst-bti-permissive-transitive-ENV = GLIBC_TUNABLES=glibc.cpu.aarch64_bti=0
tst-bti-permissive-dlopen-ENV = GLIBC_TUNABLES=glibc.cpu.aarch64_bti=0
+$(objpfx)tst-bti-unprot-audit.out: $(objpfx)tst-bti-mod-unprot-audit.so
+tst-bti-unprot-audit-ARGS = -- $(host-test-program-cmd)
+
+$(objpfx)tst-bti-prot-audit.out: $(objpfx)tst-bti-mod-prot-audit.so
+$(objpfx)tst-bti-prot-audit: $(objpfx)tst-bti-mod-prot.so
+tst-bti-prot-audit-ARGS = -- $(host-test-program-cmd)
+
+tst-bti-permissive-audit-ENV = GLIBC_TUNABLES=glibc.cpu.aarch64_bti=0
+$(objpfx)tst-bti-permissive-audit.out: $(objpfx)tst-bti-mod-unprot-audit.so
+$(objpfx)tst-bti-permissive-audit: $(objpfx)tst-bti-mod.so
+tst-bti-permissive-audit-ARGS = -- $(host-test-program-cmd)
+
define run-bti-abort-test
$(test-wrapper-env) $(run-program-env) \
$(tst-bti-abort-$*-ENV) $(host-test-program-cmd)
diff --git a/sysdeps/aarch64/tst-bti-mod-audit-skeleton.c b/sysdeps/aarch64/tst-bti-mod-audit-skeleton.c
new file mode 100644
index 0000000000..140aa8f1e6
--- /dev/null
+++ b/sysdeps/aarch64/tst-bti-mod-audit-skeleton.c
@@ -0,0 +1,47 @@
+/* Skeleton for LD_AUDIT modules to check BTI support.
+ Copyright (C) 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 <link.h>
+
+#define TST_COOKIE 0x1
+
+unsigned int
+la_version (unsigned int current)
+{
+ return LAV_CURRENT;
+}
+
+unsigned int la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
+{
+ return LA_FLG_BINDFROM | LA_FLG_BINDTO;
+}
+
+static int fun_wrapper (void)
+{
+ return 42;
+}
+
+uintptr_t
+la_symbind64 (Elf64_Sym *sym, unsigned int ndx,
+ uintptr_t *refcook, uintptr_t *defcook,
+ unsigned int *flags, const char *symname)
+{
+ return strcmp (symname, "fun") == 0
+ ? (uintptr_t) fun_wrapper : sym->st_value;
+}
diff --git a/sysdeps/aarch64/tst-bti-mod-prot-audit.c b/sysdeps/aarch64/tst-bti-mod-prot-audit.c
new file mode 100644
index 0000000000..7af9fada27
--- /dev/null
+++ b/sysdeps/aarch64/tst-bti-mod-prot-audit.c
@@ -0,0 +1 @@
+#include "tst-bti-mod-audit-skeleton.c"
diff --git a/sysdeps/aarch64/tst-bti-mod-unprot-audit.c b/sysdeps/aarch64/tst-bti-mod-unprot-audit.c
new file mode 100644
index 0000000000..7af9fada27
--- /dev/null
+++ b/sysdeps/aarch64/tst-bti-mod-unprot-audit.c
@@ -0,0 +1 @@
+#include "tst-bti-mod-audit-skeleton.c"
diff --git a/sysdeps/aarch64/tst-bti-permissive-audit.c b/sysdeps/aarch64/tst-bti-permissive-audit.c
new file mode 100644
index 0000000000..fa01088b1c
--- /dev/null
+++ b/sysdeps/aarch64/tst-bti-permissive-audit.c
@@ -0,0 +1,9 @@
+/* This test checks that process runs when an LD_AUDIT module
+ is not marked with BTI but BTI is not enforced. */
+
+#define AUDIT_MOD "tst-bti-mod-unprot-audit.so"
+#define HANDLE_RESTART TEST_COMPARE (fun (), 42)
+#define ALLOW_OUTPUT sc_allow_none
+#define CHECK_OUTPUT
+
+#include "tst-bti-skeleton-audit.c"
diff --git a/sysdeps/aarch64/tst-bti-prot-audit.c b/sysdeps/aarch64/tst-bti-prot-audit.c
new file mode 100644
index 0000000000..18cd18421e
--- /dev/null
+++ b/sysdeps/aarch64/tst-bti-prot-audit.c
@@ -0,0 +1,9 @@
+/* This test checks if the process correctly handles audit module with BTI
+ marking when BTI is enforced. */
+
+#define AUDIT_MOD "tst-bti-mod-prot-audit.so"
+#define HANDLE_RESTART TEST_COMPARE (fun (), 42)
+#define ALLOW_OUTPUT sc_allow_none
+#define CHECK_OUTPUT
+
+#include "tst-bti-skeleton-audit.c"
diff --git a/sysdeps/aarch64/tst-bti-skeleton-audit.c b/sysdeps/aarch64/tst-bti-skeleton-audit.c
new file mode 100644
index 0000000000..ae64ddf86e
--- /dev/null
+++ b/sysdeps/aarch64/tst-bti-skeleton-audit.c
@@ -0,0 +1,80 @@
+/* Skeleton for BTI tests with LD_AUDIT.
+ Copyright (C) 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 <getopt.h>
+#include <stdlib.h>
+#include <sys/auxv.h>
+#include <unistd.h>
+
+#include <support/capture_subprocess.h>
+#include <support/check.h>
+#include <support/xstdio.h>
+
+static int restart;
+#define CMDLINE_OPTIONS \
+ { "restart", no_argument, &restart, 1 },
+
+/* Defined in tst-bti-mod.c file. */
+extern int fun (void);
+typedef int (*fun_t) (void);
+
+static int
+handle_restart (void)
+{
+ HANDLE_RESTART;
+ return 0;
+}
+
+static int
+do_test (int argc, char *argv[])
+{
+ unsigned long hwcap2 = getauxval (AT_HWCAP2);
+ if ((hwcap2 & HWCAP2_BTI) == 0)
+ FAIL_UNSUPPORTED ("BTI is not supported by this system");
+
+ /* We must have either:
+ - One our fource parameters left if called initially:
+ + path to ld.so optional
+ + "--library-path" optional
+ + the library path optional
+ + the application name */
+ if (restart)
+ return handle_restart ();
+
+ char *spargv[9];
+ int i = 0;
+ for (; i < argc - 1; i++)
+ spargv[i] = argv[i + 1];
+ spargv[i++] = (char *) "--direct";
+ spargv[i++] = (char *) "--restart";
+ spargv[i] = NULL;
+
+ setenv ("LD_AUDIT", AUDIT_MOD, 0);
+ setenv ("GLIBC_TUNABLES", "glibc.cpu.aarch64_bti=1", 0);
+
+ struct support_capture_subprocess result
+ = support_capture_subprogram (spargv[0], spargv, NULL);
+ support_capture_subprocess_check (&result, "tst-bti-audit", 0, ALLOW_OUTPUT);
+
+ CHECK_OUTPUT;
+
+ return 0;
+}
+
+#define TEST_FUNCTION_ARGV do_test
+#include <support/test-driver.c>
diff --git a/sysdeps/aarch64/tst-bti-unprot-audit.c b/sysdeps/aarch64/tst-bti-unprot-audit.c
new file mode 100644
index 0000000000..3a3f74ecbc
--- /dev/null
+++ b/sysdeps/aarch64/tst-bti-unprot-audit.c
@@ -0,0 +1,13 @@
+/* This test checks if the process ignores and audit module without BTI
+ marking when BTI is enforced. */
+
+#define AUDIT_MOD "tst-bti-mod-unprot-audit.so"
+#define HANDLE_RESTART
+#define ALLOW_OUTPUT sc_allow_stderr
+#define CHECK_OUTPUT \
+ TEST_COMPARE_STRING (result.err.buffer, \
+ "ERROR: ld.so: object '" AUDIT_MOD "' " \
+ "cannot be loaded as audit interface: failed to turn " \
+ "on BTI protection; ignored.\n")
+
+#include "tst-bti-skeleton-audit.c"
--
2.43.0
More information about the Libc-alpha
mailing list