[PATCH v8 13/20] aarch64: Add glibc.cpu.aarch64_gcs_policy tunable

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Wed Jan 15 16:46:03 GMT 2025



On 14/01/25 13:03, Yury Khrustalev wrote:
> From: Szabolcs Nagy <szabolcs.nagy@arm.com>
> 
> Policy sets how GCS tunable and GCS marking turns into gcs state:
> 
> 0: state = tunable
> 1: state = marking ? tunable : (tunable && dlopen ? err : 0)
> 2: state = marking ? tunable : (tunable ? err : 0)
> 
> Describe new tunable name in the manual.
> ---
>  manual/tunables.texi                          | 32 +++++++++++++++++++
>  sysdeps/aarch64/dl-tunables.list              |  5 +++
>  .../unix/sysv/linux/aarch64/cpu-features.c    |  9 ++++--
>  sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c | 13 ++++++++
>  4 files changed, 57 insertions(+), 2 deletions(-)
> 
> diff --git a/manual/tunables.texi b/manual/tunables.texi
> index 118f490010..8f989efbcd 100644
> --- a/manual/tunables.texi
> +++ b/manual/tunables.texi
> @@ -678,6 +678,38 @@ disabled by default.
>  This tunable is specific to AArch64.
>  @end deftp
>  
> +@deftp Tunable glibc.cpu.aarch64_gcs_policy
> +The GCS policy tunable defines how the GCS tunable and the GCS marking
> +of binaries being loaded turn into GCS state (enabled, disabled or error).
> +
> +If @code{glibc.cpu.aarch64_gcs} is not set, the GCS policy tunable has no
> +effect.
> +
> +GCS policy @code{0} means that GCS is enabled if @code{glibc.cpu.aarch64_gcs}
> +is set. Any GCS marking mismatch is ignored.
> +
> +GCS policy @code{1} means that GCS is enabled if @code{glibc.cpu.aarch64_gcs}
> +is set and all binaries are GCS-marked. If GCS is required and an incompatible
> +library is loaded via @code{dlopen}, it is an error, otherwise any
> +incompatible binary will disable GCS.
> +
> +GCS policy @code{2} means that GCS is enabled if @code{glibc.cpu.aarch64_gcs}
> +is set and all binaries are GCS-marked. Any incompatible binary will result in
> +an error.
> +
> +For the avoidance of doubt, if @code{glibc.cpu.aarch64_gcs} is set and GCS
> +marking is not ignored (i.e. @code{glibc.cpu.aarch64_gcs_policy} is set to
> +either @code{1} or @code{2}), then loading an incompatible library via
> +@code{dlopen} is always an error, otherwise, with policy @code{1} GCS will be
> +disabled when one of the loaded binaries is not GCS-marked and with policy
> +@code{2} it will be an error, so GCS policy @code{2} enforces all loaded
> +binaries to be GCS-marked.

Is the policy '1' really a good semantic? I know that for testing and transition to
GCS enablement it might make sense, but we recently removed the non-executable stack
switch for dynamic shared object through dlopen (0ca8785a28515291d4ef074b5b6cfb27434c1d2b)
because this was used as vector for a RCE.

I know that is gated through a environment variable, but even though it opens some
possibility to silent disable GCS in a misconfigured environment.

> +
> +The default is @code{0} .
> +
> +This tunable is specific to AArch64.
> +@end deftp
> +
>  @node Memory Related Tunables
>  @section Memory Related Tunables
>  @cindex memory related tunables
> diff --git a/sysdeps/aarch64/dl-tunables.list b/sysdeps/aarch64/dl-tunables.list
> index 4b28341b72..7fbd77a41b 100644
> --- a/sysdeps/aarch64/dl-tunables.list
> +++ b/sysdeps/aarch64/dl-tunables.list
> @@ -26,5 +26,10 @@ glibc {
>        minval: 0
>        default: 0
>      }
> +    aarch64_gcs_policy {
> +      type: UINT_64
> +      minval: 0
> +      default: 0
> +    }
>    }
>  }
> diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
> index 1ecf6cd176..5d03a4b01b 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
> +++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
> @@ -182,6 +182,11 @@ init_cpu_features (struct cpu_features *cpu_features)
>  #endif
>  
>    if (GLRO (dl_hwcap) & HWCAP_GCS)
> -    /* GCS status may be updated later by binary compatibility checks.  */
> -    GL (dl_aarch64_gcs) = TUNABLE_GET (glibc, cpu, aarch64_gcs, uint64_t, 0);
> +    {
> +      /* GCS status may be updated later by binary compatibility checks.  */
> +      GL (dl_aarch64_gcs) = TUNABLE_GET (glibc, cpu, aarch64_gcs, uint64_t, 0);
> +      /* Fixed GCS policy.  */
> +      GLRO (dl_aarch64_gcs_policy) =
> +	TUNABLE_GET (glibc, cpu, aarch64_gcs_policy, uint64_t, 0);
> +    }
>  }
> diff --git a/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c b/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c
> index 66287b4216..bcfc3fe030 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c
> +++ b/sysdeps/unix/sysv/linux/aarch64/dl-procinfo.c
> @@ -54,6 +54,19 @@ PROCINFO_CLASS struct cpu_features _dl_aarch64_cpu_features
>  # else
>  ,
>  # endif
> +# if !defined PROCINFO_DECL && defined SHARED
> +  ._dl_aarch64_gcs_policy
> +# else
> +PROCINFO_CLASS uint64_t _dl_aarch64_gcs_policy
> +# endif
> +# ifndef PROCINFO_DECL
> += 0
> +# endif
> +# if !defined SHARED || defined PROCINFO_DECL
> +;
> +# else
> +,
> +# endif
>  #endif
>  
>  /* Number of HWCAP bits set.  */



More information about the Libc-alpha mailing list