[PATCH 1/1] aarch64: Add LD_DEBUG=protect to log BTI and GCS warnings

Florian Weimer fw@deneb.enyo.de
Mon Dec 8 14:48:30 GMT 2025


* Yury Khrustalev:

> diff --git a/misc/tst-dl-debug-protect.sh b/misc/tst-dl-debug-protect.sh
> new file mode 100644
> index 0000000000..865c9e2977
> --- /dev/null
> +++ b/misc/tst-dl-debug-protect.sh
> @@ -0,0 +1,48 @@
> +#!/bin/sh
> +# Test for protection warnings in dynamic linker.
> +# 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/>.
> +
> +# Arguments are from Makefile.
> +objpfx="$1"
> +wrapper="$2"
> +loader="$3"
> +runenv="$4"
> +pattern="$5"
> +program="$6"
> +
> +output="${objpfx}tst-dl-debug-protect.debug"
> +rm -f "${output}".*
> +
> +eval "${wrapper}" \
> +  LD_DEBUG=protect LD_DEBUG_OUTPUT="${output}" ${runenv} \
> +  "${loader}" "${program}"
> +rc=$?
> +
> +if test $rc -eq 77; then
> +  echo "Test is not supported"
> +  rm -f "${output}".*
> +  exit 77
> +fi
> +
> +output=$(ls "${output}".*)
> +cat "${output}"
> +if ! grep -q "${pattern}" "${output}"; then
> +  echo "Could not find expected pattern in '${pattern}'"
> +  exit 1
> +fi
> +rm -f "${output}"

Should this go into elf/?  And it's not actually a test, but a
building block for tests.  So the file header should say so, and maybe
add a comment about how the script is expected to be used.

> diff --git a/sysdeps/aarch64/dl-bti.c b/sysdeps/aarch64/dl-bti.c
> index e654dde484..284412f1ab 100644
> --- a/sysdeps/aarch64/dl-bti.c
> +++ b/sysdeps/aarch64/dl-bti.c
> @@ -102,7 +102,13 @@ _dl_bti_check (struct link_map *l, const char *program)
>        if (is_rtld_link_map (dep->l_real))
>  	continue;
>  #endif
> -      if (enforce_bti && !dep->l_mach.bti)
> -	bti_failed (dep, program);
> +      if (!dep->l_mach.bti)
> +	{
> +	  if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_PROTECT))
> +	    _dl_debug_printf ("AArch64 BTI: unmarked module %s\n",
> +			      dep->l_name && dep->l_name[0] ? dep->l_name : program);
> +	  if (enforce_bti)
> +	    bti_failed (dep, program);
> +	}
>      }
>  }
> diff --git a/sysdeps/aarch64/dl-gcs.c b/sysdeps/aarch64/dl-gcs.c
> index 4ac86a5d6f..853929aa82 100644
> --- a/sysdeps/aarch64/dl-gcs.c
> +++ b/sysdeps/aarch64/dl-gcs.c
> @@ -61,6 +61,9 @@ check_gcs (struct link_map *l, const char *program, bool enforced)
>    /* Binary is marked, all good.  */
>    if (l->l_mach.gcs)
>      return true;
> +  if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_PROTECT))
> +    _dl_debug_printf ("AArch64 GCS: unmarked module %s\n",
> +		      l->l_name && l->l_name[0] ? l->l_name : program);
>    /* Binary is not marked and loaded via dlopen: abort.  */
>    if (program == NULL)
>      fail (l, program);

The log messages should somehow related this with “projection”, so
that it is clearer what they imply to someone who uses LD_DEBUG=all,
but doesn't know about BTI/GCS.

I'm not sure if “unmarked” is clear enough in this context.  It could
be interpreted as an unmarking action taken by the dynamic linker.
Perhaps “incompatible” is clearer?

Is there a “marked as incompatible” state?

Thanks,
Florian


More information about the Libc-alpha mailing list