[PATCH v2] Detect ld.so and libc.so version inconsistency during startup
Florian Weimer
fweimer@redhat.com
Tue Aug 23 19:13:22 GMT 2022
* Florian Weimer via Libc-alpha:
> The files NEWS, include/link.h, and sysdeps/generic/ldsodefs.h
> contribute to the version fingerprint used for detection. The
> fingerprint can be further refined using the --with-extra-version-id
> configure argument.
>
> _dl_call_libc_early_init is replaced with _dl_lookup_libc_early_init.
> The new function is used store a pointer to libc.so's
> __libc_early_init function in the libc_map_early_init member of the
> ld.so namespace structure. This function pointer can then be called
> directly, so the separate invocation function is no longer needed.
>
> The versioned symbol lookup needs the symbol versioning data
> structures, so the initialization of libc_map and libc_map_early_init
> is now done from _dl_check_map_versions, after this information
> becomes available. (_dl_map_object_from_fd does not set this up
> in time, so the initialization code had to be moved from there.)
> This means that the separate initialization code can be removed from
> dl_main because _dl_check_map_versions covers all maps, including
> the initial executable loaded by the kernel. The lookup still happens
> before relocation and the invocation of IFUNC resolvers, so IFUNC
> resolvers are protected from ABI mismatch.
>
> The __libc_early_init function pointer is not protected because
> so little code runs between the pointer write and the invocation
> (only dynamic linker code and IFUNC resolvers).
>
> ---
> v2: Really quite different. I moved the __libc_early_init lookup before
> relocation processing, which had a bunch of knock-on effects.
> Re-tested on i386-linux-gnu and x86_64-linux-gnu.
> build-many-glibcs.py is still running.
build-many-glibcs.py passed. I also manually verified with GDB that
libc_map is still initialized when running the install libc.so.6
directly (not with an explicit loader invocation):
(gdb) print _rtld_global._dl_ns[0].libc_map
$1 = (struct link_map *) 0x7ffff7ffe380
(gdb) print _rtld_global._dl_ns[0].libc_map_early_init
$2 = (void (*)(_Bool)) 0x5555556909f0 <__libc_early_init_jBsH275t>
So that special initialization code I removed from the !rtld_is_main
case really isn't needed anymore.
Thanks,
Florian
More information about the Libc-alpha
mailing list