[PATCH] elf: Avoid type aliasing violation on __tunable_get_{default, val}

Siddhesh Poyarekar siddhesh@gotplt.org
Tue Dec 12 20:30:01 GMT 2023


On 2023-11-29 09:17, Adhemerval Zanella wrote:
> Checked on x86_64-linux-gnu.
> ---
>   elf/dl-tunables.c | 54 ++++++++++++++++++-----------------------------
>   1 file changed, 20 insertions(+), 34 deletions(-)
> 
> diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
> index 644d21d1b0..85af249bb2 100644
> --- a/elf/dl-tunables.c
> +++ b/elf/dl-tunables.c
> @@ -340,37 +340,47 @@ __tunables_print (void)
>       }
>   }
>   
> -void
> -__tunable_get_default (tunable_id_t id, void *valp)
> +static void
> +get_tunable (tunable_type_code_t type_code, void *valp,
> +	     const tunable_val_t *tunable)
>   {
> -  tunable_t *cur = &tunable_list[id];
> -
> -  switch (cur->type.type_code)
> +  switch (type_code)
>       {
>       case TUNABLE_TYPE_UINT_64:
>   	{
> -	  *((uint64_t *) valp) = (uint64_t) cur->def.numval;
> +	  uint64_t v = tunable->numval;
> +	  memcpy (valp, &v, sizeof v);

How about splitting numval instead so that we have:

typedef union
{
   uint64_t u64;
   int32_t i32;
   size_t sz;
   const char *strval;
} tunable_val_t;

If you want to avoid cases for valp too, we could alter the signature to 
tunable_val_t * and then fix up __tunable_get_val to use tunable_val_t * 
instead of void *.

Thanks,
Sid

>   	  break;
>   	}
>       case TUNABLE_TYPE_INT_32:
>   	{
> -	  *((int32_t *) valp) = (int32_t) cur->def.numval;
> +	  uint32_t v = tunable->numval;
> +	  memcpy (valp, &v, sizeof v);
>   	  break;
>   	}
>       case TUNABLE_TYPE_SIZE_T:
>   	{
> -	  *((size_t *) valp) = (size_t) cur->def.numval;
> +	  size_t v = tunable->numval;
> +	  memcpy (valp, &v, sizeof v);
>   	  break;
>   	}
>       case TUNABLE_TYPE_STRING:
>   	{
> -	  *((const char **)valp) = cur->def.strval;
> +	  memcpy (valp, &tunable->strval, sizeof (char *));
>   	  break;
>   	}
>       default:
>         __builtin_unreachable ();
>       }
>   }
> +
> +void
> +__tunable_get_default (tunable_id_t id, void *valp)
> +{
> +  tunable_t *cur = &tunable_list[id];
> +
> +  get_tunable (cur->type.type_code, valp, &cur->def);
> +}
>   rtld_hidden_def (__tunable_get_default)
>   
>   /* Set the tunable value.  This is called by the module that the tunable exists
> @@ -380,31 +390,7 @@ __tunable_get_val (tunable_id_t id, void *valp, tunable_callback_t callback)
>   {
>     tunable_t *cur = &tunable_list[id];
>   
> -  switch (cur->type.type_code)
> -    {
> -    case TUNABLE_TYPE_UINT_64:
> -	{
> -	  *((uint64_t *) valp) = (uint64_t) cur->val.numval;
> -	  break;
> -	}
> -    case TUNABLE_TYPE_INT_32:
> -	{
> -	  *((int32_t *) valp) = (int32_t) cur->val.numval;
> -	  break;
> -	}
> -    case TUNABLE_TYPE_SIZE_T:
> -	{
> -	  *((size_t *) valp) = (size_t) cur->val.numval;
> -	  break;
> -	}
> -    case TUNABLE_TYPE_STRING:
> -	{
> -	  *((const char **)valp) = cur->val.strval;
> -	  break;
> -	}
> -    default:
> -      __builtin_unreachable ();
> -    }
> +  get_tunable (cur->type.type_code, valp, &cur->val);
>   
>     if (cur->initialized && callback != NULL)
>       callback (&cur->val);


More information about the Libc-alpha mailing list