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

Message ID 20231129141726.3325945-1-adhemerval.zanella@linaro.org
State Changes Requested
Delegated to: Siddhesh Poyarekar
Headers
Series elf: Avoid type aliasing violation on __tunable_get_{default, val} |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Testing passed
redhat-pt-bot/TryBot-32bit success Build for i686
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Testing passed

Commit Message

Adhemerval Zanella Netto Nov. 29, 2023, 2:17 p.m. UTC
  Checked on x86_64-linux-gnu.
---
 elf/dl-tunables.c | 54 ++++++++++++++++++-----------------------------
 1 file changed, 20 insertions(+), 34 deletions(-)
  

Comments

Siddhesh Poyarekar Dec. 12, 2023, 8:30 p.m. UTC | #1
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);
  

Patch

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);
 	  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);