[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