[PATCH v7 1/4] Add system-wide tunables: ldconfig part
Arjun Shankar
arjun@redhat.com
Mon Jun 1 11:56:49 GMT 2026
Hi DJ,
In print_extensions:
> + /* Check that COUNT won't overflow our data block. */
> + assert (ext->sections[cache_extension_tag_tunables].base
> + + ext->sections[cache_extension_tag_tunables].size
> + >= (void *) & tec[count]);
Should we make it stricter with a check for exact size? Something like:
sizeof (tunable_header_cached)
+ count * sizeof (tunable_entry_cached)
== ext->sections[cache_extension_tag_tunables].size
I'm also wondering if it's worth checking for overflow before the
addition. Maybe it's overkill, but I wanted to mention it.
...
> @@ -498,6 +528,28 @@ write_extensions (int fd, uint32_t str_offset,
> ext->sections[xid].size = hwcaps_size;
> }
>
> + struct tunable_header_cached *tunable_data;
> + size_t tunable_size;
> + size_t tunable_aligner = 0;
> +
> + tunable_data = get_tunconf_ext (str_offset);
This is non-NULL even when there are no tunables, leading to a
superfluous extension section and data being written here.
...
> @@ -1089,6 +1101,9 @@ main (int argc, char **argv)
> if (config_file == NULL)
> config_file = LD_SO_CONF;
>
> + if (tunconfig_file == NULL)
> + tunconfig_file = TUNABLES_CONF;
> +
> if (opt_print_cache)
> {
> if (opt_chroot != NULL)
> @@ -1164,6 +1179,8 @@ main (int argc, char **argv)
>
> search_dirs ();
>
> + parse_tunconf (tunconfig_file, opt_chroot);
> +
Looks like it could be guarded by opt_build_cache since nothing else
consumes the parsed data.
> +++ b/elf/tunconf.c
...
> +/* Declared in chroot_canon.c. */
> +extern char *chroot_canon (const char *chroot, const char *name);
Looks like it's declared in sysdeps/generic/ldconfig.h. Not very sure
if that gets overridden by some non-generic variant.
...
> +struct tunable_entry_int {
> + struct stringtable_entry *name;
> + struct stringtable_entry *value;
> + TOP top;
> + int tunable_id;
> + int value_is_negative:1;
> + int value_was_parsed:1;
> + unsigned long long value_ull;
> + signed long long value_sll;
These last four are never written to by ldconfig.
> +
> + struct tunable_entry_int *next;
> +};
> +
> +struct tunable_entry_int *entry_list;
> +struct tunable_entry_int **entry_list_next = &entry_list;
This could be local to add_tunable. It doesn't appear to be used elsewhere.
In add_tunable:
> + id = -1;
> + for (i = 0; i < array_length (tunable_list); i ++)
> + if (strcmp (tunable_list[i].name, name) == 0)
> + {
> + id = i;
> + break;
> + }
Here, when we don't find the tunable (id == -1), we store it anyway. This
makes sense since ldconfig might not know about a valid tunable. Is this
worth reporting to the user? A message can guard against situations where a
subtly misspelled or typo-ed tunable doesn't get silently ignored at caching
time as well as loading time.
> +
> + entry = (struct tunable_entry_int *) xcalloc (sizeof (struct tunable_entry_int), 1);
> + entry->name = cache_store_string (name);
> + entry->value = cache_store_string (value);
> + entry->tunable_id = id;
> + entry->top = top;
The parsing of numeric tunable values into the remaining fields should
happen here, if at all.
> +struct tunable_header_cached *
> +get_tunconf_ext (uint32_t string_table_offset)
> +{
> + struct tunable_entry_int *tei;
> + struct tunable_header_cached *thc;
> + size_t count;
> + size_t size;
> +
> + /* First, count the number of entries we have. */
> + tei = entry_list;
> + count = 0;
> + while (tei != NULL)
> + {
> + ++ count;
> + tei = tei->next;
> + }
Can we return early here with an empty/NULL result when count is 0?
> + /* Allocate enough space for the whole cached block. */
> + size = sizeof (struct tunable_header_cached)
> + + sizeof (struct tunable_entry_cached) * count;
> + thc = (struct tunable_header_cached *) malloc (size);
> +
> + if (thc == NULL)
> + {
> + error (0, 0, _("Unable to allocate %zu bytes in get_tunable_ext"), size);
Typo. Should be get_tunconf_ext.
> + return NULL;
> + }
> +
> + /* Now, fill in the structures. */
> +
> + thc->signature = TUNCONF_SIGNATURE;
> + thc->version = TUNCONF_VERSION;
> + thc->num_tunables = count;
> + thc->unused_1 = 0;
> +
> + tei = entry_list;
> + count = 0;
> + while (tei != NULL)
> + {
> + struct tunable_entry_cached *tec;
> +
> + tec = & ( thc->tunables[count] );
> +
> + tec->flags = 0;
> + if (tei->value_was_parsed)
This will always be false.
> + tec->flags |= TUNCONF_FLAG_PARSED;
> + if (tei->value_is_negative)
This as well.
Cheers,
Arjun
More information about the Libc-alpha
mailing list