[PATCH v4 2/3] aarch64: Support enforcing BTI on dependencies

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Wed Dec 3 15:53:22 GMT 2025



On 01/12/25 13:14, Yury Khrustalev wrote:
> Add glibc.cpu.aarch64_bti tunable with 2 values:
> 
>  - permissive (default)
>  - enforced
> 
> and use this tunable to enforce BTI marking on dependencies
> when the enforced option is selected.

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

> ---
>  manual/tunables.texi                           | 17 +++++++++++++++++
>  sysdeps/aarch64/cpu-features.h                 |  5 +++++
>  sysdeps/aarch64/dl-bti.c                       | 15 +++++++++++++++
>  sysdeps/aarch64/dl-tunables.list               |  6 ++++++
>  sysdeps/aarch64/linkmap.h                      |  1 +
>  sysdeps/unix/sysv/linux/aarch64/cpu-features.c |  2 ++
>  sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c  | 16 ++++++++++++++++
>  7 files changed, 62 insertions(+)
> 
> diff --git a/manual/tunables.texi b/manual/tunables.texi
> index 4d3c6e9933..7956df919b 100644
> --- a/manual/tunables.texi
> +++ b/manual/tunables.texi
> @@ -598,6 +598,23 @@ This tunable is specific to x86-64 and effective only when the lazy
>  binding is disabled.
>  @end deftp
>  
> +@deftp Tunable glibc.cpu.aarch64_bti
> +This tunable controls Branch Target Identification (BTI) handling for the
> +process. This handling is implemented via protecting the memory mapping
> +with @code{PROT_BTI} for modules that are marked with the appropriate ELF
> +property @code{GNU_PROPERTY_AARCH64_FEATURE_1_BTI} (see Program Loading in
> +@url{https://github.com/ARM-software/abi-aa/blob/main/sysvabi64/sysvabi64.rst}).
> +
> +Accepted values are:
> +
> +0 = permissive: BTI protection is enabled only for modules that have BTI
> +marking (default).
> +
> +1 = enforced: if a module that does not have BTI marking is loaded, it is
> +an error (either a process abort or a @code{dlopen} error if this binary
> +is loaded via @code{dlopen}).
> +@end deftp
> +
>  @deftp Tunable glibc.cpu.aarch64_gcs
>  This tunable controls Guarded Control Stack (GCS) for the process.
>  
> diff --git a/sysdeps/aarch64/cpu-features.h b/sysdeps/aarch64/cpu-features.h
> index ef4e947e8c..855990b575 100644
> --- a/sysdeps/aarch64/cpu-features.h
> +++ b/sysdeps/aarch64/cpu-features.h
> @@ -54,6 +54,11 @@
>  			     || (MIDR_PARTNUM(midr) == 0x002		\
>  			         && MIDR_VARIANT(midr) == 0)))
>  
> +enum {
> +  BTI_CHECK_PERMISSIVE = 0,
> +  BTI_CHECK_ENFORCED = 1,
> +};
> +
>  struct cpu_features
>  {
>    uint64_t midr_el1;
> diff --git a/sysdeps/aarch64/dl-bti.c b/sysdeps/aarch64/dl-bti.c
> index de6130470e..e654dde484 100644
> --- a/sysdeps/aarch64/dl-bti.c
> +++ b/sysdeps/aarch64/dl-bti.c
> @@ -31,6 +31,9 @@
>  void
>  _dl_bti_protect (struct link_map *map, int fd)
>  {
> +  /* If we try to enable BTI protection, MAP must be BTI marked.  */
> +  map->l_mach.bti = true;
> +
>    const size_t pagesz = GLRO(dl_pagesize);
>    const ElfW(Phdr) *phdr;
>  
> @@ -84,10 +87,22 @@ _dl_bti_check (struct link_map *l, const char *program)
>    if (l->l_mach.bti_fail)
>      bti_failed (l, program);
>  
> +  /* We enforce BTI if tunable is set and if this object has BTI marking.  */
> +  bool enforce_bti = GLRO (dl_aarch64_bti) == BTI_CHECK_ENFORCED;
> +
>    for (unsigned int i = 0; i < l->l_searchlist.r_nlist; i++)
>      {
>        struct link_map *dep = l->l_searchlist.r_list[i];
>        if (dep->l_mach.bti_fail)
>  	bti_failed (dep, program);
> +#ifdef SHARED
> +      /* Ignore BTI marking on ld.so: its properties are not processed, and
> +	 the kernel is responsible for setting up BTI protection for the
> +	 loader.  */
> +      if (is_rtld_link_map (dep->l_real))
> +	continue;
> +#endif
> +      if (enforce_bti && !dep->l_mach.bti)
> +	bti_failed (dep, program);
>      }
>  }
> diff --git a/sysdeps/aarch64/dl-tunables.list b/sysdeps/aarch64/dl-tunables.list
> index d461c1e9db..40757ac046 100644
> --- a/sysdeps/aarch64/dl-tunables.list
> +++ b/sysdeps/aarch64/dl-tunables.list
> @@ -21,6 +21,12 @@ glibc {
>      name {
>        type: STRING
>      }
> +    aarch64_bti {
> +      type: UINT_64
> +      minval: 0
> +      maxval: 1
> +      default: 0
> +    }
>      aarch64_gcs {
>        type: UINT_64
>        minval: 0
> diff --git a/sysdeps/aarch64/linkmap.h b/sysdeps/aarch64/linkmap.h
> index e56c890aea..4cd0492209 100644
> --- a/sysdeps/aarch64/linkmap.h
> +++ b/sysdeps/aarch64/linkmap.h
> @@ -24,4 +24,5 @@ struct link_map_machine
>    void *tlsdesc_table;	  /* Address of TLS descriptor hash table.  */
>    bool bti_fail;	  /* Failed to enable Branch Target Identification.  */
>    bool gcs;		  /* Guarded Control Stack marking.  */
> +  bool bti;		  /* Branch Target Identification marking.  */
>  };
> diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
> index 1acc82d077..a05a4ce794 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
> +++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
> @@ -137,6 +137,8 @@ init_cpu_features (struct cpu_features *cpu_features)
>  
>    /* Check if BTI is supported.  */
>    cpu_features->bti = GLRO (dl_hwcap2) & HWCAP2_BTI;
> +  if (cpu_features->bti)
> +    GLRO (dl_aarch64_bti) = TUNABLE_GET (glibc, cpu, aarch64_bti, uint64_t, 0);
>  
>    /* Setup memory tagging support if the HW and kernel support it, and if
>       the user has requested it.  */
> diff --git a/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c b/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c
> index 20966e0478..7c34c8ddba 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c
> +++ b/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c
> @@ -56,5 +56,21 @@ PROCINFO_CLASS struct cpu_features _dl_aarch64_cpu_features
>  # endif
>  #endif
>  
> +#if !IS_IN (ldconfig)
> +# if !defined PROCINFO_DECL && defined SHARED
> +  ._dl_aarch64_bti
> +# else
> +PROCINFO_CLASS unsigned long _dl_aarch64_bti
> +# endif
> +# ifndef PROCINFO_DECL
> += BTI_CHECK_PERMISSIVE
> +# endif
> +# if !defined SHARED || defined PROCINFO_DECL
> +;
> +# else
> +,
> +# endif
> +#endif
> +
>  #undef PROCINFO_DECL
>  #undef PROCINFO_CLASS



More information about the Libc-alpha mailing list