[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