about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--INSTALL10
-rw-r--r--Makerules14
-rw-r--r--NEWS7
-rw-r--r--config.make.in1
-rwxr-xr-xconfigure11
-rw-r--r--configure.ac5
-rw-r--r--elf/Makefile2
-rw-r--r--elf/Versions4
-rw-r--r--elf/dl-call-libc-early-init.c (renamed from elf/dl-lookup_libc_early_init.c)23
-rw-r--r--elf/dl-load.c9
-rw-r--r--elf/dl-open.c4
-rw-r--r--elf/dl-version.c18
-rw-r--r--elf/libc-early-init.h21
-rw-r--r--elf/rtld.c12
-rw-r--r--manual/install.texi9
-rw-r--r--scripts/libc_early_init_name.py89
-rw-r--r--sysdeps/generic/ldsodefs.h4
17 files changed, 45 insertions, 198 deletions
diff --git a/INSTALL b/INSTALL
index 6470cd3d25..659f75a97f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -120,16 +120,6 @@ if 'CFLAGS' is specified it must enable optimization.  For example:
      compiler flags which target a later instruction set architecture
      (ISA).
 
-'--with-extra-version-id=STRING'
-     Use STRING as part of the fingerprint that is used by the dynamic
-     linker to detect an incompatible version of 'libc.so'.  For
-     example, STRING could be the full package version and release
-     string used by a distribution build of the GNU C Library.  This
-     way, concurrent process creation during a package update will fail
-     with an error message, _error while loading shared libraries:
-     /lib64/libc.so.6: ld.so/libc.so mismatch detected (upgrade in
-     progress?)_, rather than crashing mysteriously.
-
 '--with-timeoutfactor=NUM'
      Specify an integer NUM to scale the timeout of test programs.  This
      factor can be changed at run time using 'TIMEOUTFACTOR' environment
diff --git a/Makerules b/Makerules
index 756c1f181c..d1e139d03c 100644
--- a/Makerules
+++ b/Makerules
@@ -112,20 +112,6 @@ before-compile := $(common-objpfx)first-versions.h \
 		  $(common-objpfx)ldbl-compat-choose.h $(before-compile)
 $(common-objpfx)first-versions.h: $(common-objpfx)versions.stmp
 $(common-objpfx)ldbl-compat-choose.h: $(common-objpfx)versions.stmp
-
-# libc_early_init_name.h provides the actual name of the
-# __libc_early_init function.  It is used as a protocol version marker
-# between ld.so and libc.so
-before-compile := $(common-objpfx)libc_early_init_name.h $(before-compile)
-libc_early_init_name-deps = \
-  $(..)NEWS $(..)sysdeps/generic/ldsodefs.h $(..)include/link.h
-$(common-objpfx)libc_early_init_name.h: $(..)scripts/libc_early_init_name.py \
-  $(common-objpfx)config.make $(libc_early_init_name-deps)
-	$(PYTHON) $(..)scripts/libc_early_init_name.py \
-	  --output=$@T \
-	  --extra-version-id="$(extra-version-id)" \
-	  $(libc_early_init_name-deps)
-	$(move-if-change) $@T $@
 endif # avoid-generated
 endif # $(build-shared) = yes
 
diff --git a/NEWS b/NEWS
index 9d3c8c5ed8..f9bef48a8f 100644
--- a/NEWS
+++ b/NEWS
@@ -9,12 +9,7 @@ Version 2.37
 
 Major new features:
 
-* The dynamic loader now prints an error message, "ld.so/libc.so
-  mismatch detected (upgrade in progress?)" if it detects that the
-  version of libc.so it loaded comes from a different build of glibc.
-  The new configure option --with-extra-version-id can be used to
-  specify an arbitrary string that affects the computation of the
-  version fingerprint.
+  [Add new features here]
 
 Deprecated and removed features, and other changes affecting compatibility:
 
diff --git a/config.make.in b/config.make.in
index ecaffbfd4b..d7c416cbea 100644
--- a/config.make.in
+++ b/config.make.in
@@ -98,7 +98,6 @@ build-hardcoded-path-in-tests= @hardcoded_path_in_tests@
 build-pt-chown = @build_pt_chown@
 have-tunables = @have_tunables@
 pthread-in-libc = @pthread_in_libc@
-extra-version-id = @extra_version_id@
 
 # Build tools.
 CC = @CC@
diff --git a/configure b/configure
index c576f9f133..ff2c406b3b 100755
--- a/configure
+++ b/configure
@@ -760,7 +760,6 @@ with_headers
 with_default_link
 with_nonshared_cflags
 with_rtld_early_cflags
-with_extra_version_id
 with_timeoutfactor
 enable_sanity_checks
 enable_shared
@@ -1482,9 +1481,6 @@ Optional Packages:
                           build nonshared libraries with additional CFLAGS
   --with-rtld-early-cflags=CFLAGS
                           build early initialization with additional CFLAGS
-  --extra-version-id=STRING
-                          specify an extra version string to use in internal
-                          ABI checks
   --with-timeoutfactor=NUM
                           specify an integer to scale the timeout
   --with-cpu=CPU          select code for CPU variant
@@ -3401,13 +3397,6 @@ fi
 
 
 
-# Check whether --with-extra-version-id was given.
-if test "${with_extra_version_id+set}" = set; then :
-  withval=$with_extra_version_id; extra_version_id="$withval"
-fi
-
-
-
 # Check whether --with-timeoutfactor was given.
 if test "${with_timeoutfactor+set}" = set; then :
   withval=$with_timeoutfactor; timeoutfactor=$withval
diff --git a/configure.ac b/configure.ac
index 68baeee4d7..eb5bc6a131 100644
--- a/configure.ac
+++ b/configure.ac
@@ -169,11 +169,6 @@ AC_ARG_WITH([rtld-early-cflags],
 	    [rtld_early_cflags=])
 AC_SUBST(rtld_early_cflags)
 
-AC_ARG_WITH([extra-version-id],
-	    AS_HELP_STRING([--extra-version-id=STRING],
-			   [specify an extra version string to use in internal ABI checks]),
-	    [extra_version_id="$withval"])
-
 AC_ARG_WITH([timeoutfactor],
 	    AS_HELP_STRING([--with-timeoutfactor=NUM],
 			   [specify an integer to scale the timeout]),
diff --git a/elf/Makefile b/elf/Makefile
index bc68150a37..3928a08787 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -52,6 +52,7 @@ routines = \
 # The core dynamic linking functions are in libc for the static and
 # profiled libraries.
 dl-routines = \
+  dl-call-libc-early-init \
   dl-close \
   dl-debug \
   dl-debug-symbols \
@@ -64,7 +65,6 @@ dl-routines = \
   dl-load \
   dl-lookup \
   dl-lookup-direct \
-  dl-lookup_libc_early_init \
   dl-minimal-malloc \
   dl-misc \
   dl-object \
diff --git a/elf/Versions b/elf/Versions
index 6260c0fe03..a9ff278de7 100644
--- a/elf/Versions
+++ b/elf/Versions
@@ -29,8 +29,8 @@ libc {
     __placeholder_only_for_empty_version_map;
   }
   GLIBC_PRIVATE {
-    # A pattern is needed here because the suffix is dynamically generated.
-    __libc_early_init_*;
+    # functions used in other libraries
+    __libc_early_init;
 
     # Internal error handling support.  Interposes the functions in ld.so.
     _dl_signal_exception; _dl_catch_exception;
diff --git a/elf/dl-lookup_libc_early_init.c b/elf/dl-call-libc-early-init.c
index 64bc287a05..ee9860e3ab 100644
--- a/elf/dl-lookup_libc_early_init.c
+++ b/elf/dl-call-libc-early-init.c
@@ -1,4 +1,4 @@
-/* Find the address of the __libc_early_init function.
+/* Invoke the early initialization function in libc.so.
    Copyright (C) 2020-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,21 +16,26 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <assert.h>
 #include <ldsodefs.h>
 #include <libc-early-init.h>
 #include <link.h>
 #include <stddef.h>
 
-__typeof (__libc_early_init) *
-_dl_lookup_libc_early_init (struct link_map *libc_map)
+void
+_dl_call_libc_early_init (struct link_map *libc_map, _Bool initial)
 {
+  /* There is nothing to do if we did not actually load libc.so.  */
+  if (libc_map == NULL)
+    return;
+
   const ElfW(Sym) *sym
-    = _dl_lookup_direct (libc_map, LIBC_EARLY_INIT_NAME_STRING,
-                         LIBC_EARLY_INIT_GNU_HASH,
+    = _dl_lookup_direct (libc_map, "__libc_early_init",
+                         0x069682ac, /* dl_new_hash output.  */
                          "GLIBC_PRIVATE",
                          0x0963cf85); /* _dl_elf_hash output.  */
-  if (sym == NULL)
-    _dl_signal_error (0, libc_map->l_name, NULL, "\
-ld.so/libc.so mismatch detected (upgrade in progress?)");
-  return DL_SYMBOL_ADDRESS (libc_map, sym);
+  assert (sym != NULL);
+  __typeof (__libc_early_init) *early_init
+    = DL_SYMBOL_ADDRESS (libc_map, sym);
+  early_init (initial);
 }
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 00e08b5500..1ad0868dad 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -31,6 +31,7 @@
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <gnu/lib-names.h>
 
 /* Type for the buffer we put the ELF header and hopefully the program
    header.  This buffer does not really have to be too large.  In most
@@ -1465,6 +1466,14 @@ cannot enable executable stack as shared object requires");
     add_name_to_object (l, ((const char *) D_PTR (l, l_info[DT_STRTAB])
 			    + l->l_info[DT_SONAME]->d_un.d_val));
 
+  /* If we have newly loaded libc.so, update the namespace
+     description.  */
+  if (GL(dl_ns)[nsid].libc_map == NULL
+      && l->l_info[DT_SONAME] != NULL
+      && strcmp (((const char *) D_PTR (l, l_info[DT_STRTAB])
+		  + l->l_info[DT_SONAME]->d_un.d_val), LIBC_SO) == 0)
+    GL(dl_ns)[nsid].libc_map = l;
+
   /* _dl_close can only eventually undo the module ID assignment (via
      remove_slotinfo) if this function returns a pointer to a link
      map.  Therefore, delay this step until all possibilities for
diff --git a/elf/dl-open.c b/elf/dl-open.c
index dcc24130fe..a23e65926b 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -760,8 +760,8 @@ dl_open_worker_begin (void *a)
   if (!args->libc_already_loaded)
     {
       /* dlopen cannot be used to load an initial libc by design.  */
-      if (GL(dl_ns)[args->nsid].libc_map != NULL)
-	GL(dl_ns)[args->nsid].libc_map_early_init (false);
+      struct link_map *libc_map = GL(dl_ns)[args->nsid].libc_map;
+      _dl_call_libc_early_init (libc_map, false);
     }
 
   args->worker_continue = true;
diff --git a/elf/dl-version.c b/elf/dl-version.c
index d9ec44eed6..cda0889209 100644
--- a/elf/dl-version.c
+++ b/elf/dl-version.c
@@ -23,8 +23,6 @@
 #include <string.h>
 #include <ldsodefs.h>
 #include <_itoa.h>
-#include <gnu/lib-names.h>
-#include <libc-early-init.h>
 
 #include <assert.h>
 
@@ -361,22 +359,6 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
 	}
     }
 
-  /* Detect a libc.so loaded into this namespace.  The
-     __libc_early_init lookup below means that we have to do this
-     after parsing the version data.  */
-  if (GL(dl_ns)[map->l_ns].libc_map == NULL
-      && map->l_info[DT_SONAME] != NULL
-      && strcmp (((const char *) D_PTR (map, l_info[DT_STRTAB])
-		  + map->l_info[DT_SONAME]->d_un.d_val), LIBC_SO) == 0)
-    {
-      /* Look up this symbol early to trigger a mismatch error before
-	 relocation (which may call IFUNC resolvers, and those can
-	 have an internal ABI dependency).  */
-      GL(dl_ns)[map->l_ns].libc_map_early_init
-	= _dl_lookup_libc_early_init (map);
-      GL(dl_ns)[map->l_ns].libc_map = map;
-    }
-
   /* When there is a DT_VERNEED entry with libc.so on DT_NEEDED, issue
      an error if there is a DT_RELR entry without GLIBC_ABI_DT_RELR
      dependency.  */
diff --git a/elf/libc-early-init.h b/elf/libc-early-init.h
index ac8c204bc7..a8edfadfb0 100644
--- a/elf/libc-early-init.h
+++ b/elf/libc-early-init.h
@@ -19,10 +19,13 @@
 #ifndef _LIBC_EARLY_INIT_H
 #define _LIBC_EARLY_INIT_H
 
-#include <libc_early_init_name.h>
-
 struct link_map;
 
+/* If LIBC_MAP is not NULL, look up the __libc_early_init symbol in it
+   and call this function, with INITIAL as the argument.  */
+void _dl_call_libc_early_init (struct link_map *libc_map, _Bool initial)
+  attribute_hidden;
+
 /* In the shared case, this function is defined in libc.so and invoked
    from ld.so (or on the fist static dlopen) after complete relocation
    of a new loaded libc.so, but before user-defined ELF constructors
@@ -30,18 +33,6 @@ struct link_map;
    startup code.  If INITIAL is true, the libc being initialized is
    the libc for the main program.  INITIAL is false for libcs loaded
    for audit modules, dlmopen, and static dlopen.  */
-void __libc_early_init (_Bool initial)
-#ifdef SHARED
-/* Redirect to the actual implementation name.  */
-  __asm__ (LIBC_EARLY_INIT_NAME_STRING)
-#endif
-  ;
-
-/* Attempts to find the appropriately named __libc_early_init function
-   in LIBC_MAP.  On lookup failure, an exception is signaled,
-   indicating an ld.so/libc.so mismatch.  */
-__typeof (__libc_early_init) *_dl_lookup_libc_early_init (struct link_map *
-                                                          libc_map)
-  attribute_hidden;
+void __libc_early_init (_Bool initial);
 
 #endif /* _LIBC_EARLY_INIT_H */
diff --git a/elf/rtld.c b/elf/rtld.c
index 910075c37f..cbbaf4a331 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1707,6 +1707,15 @@ dl_main (const ElfW(Phdr) *phdr,
       /* Extract the contents of the dynamic section for easy access.  */
       elf_get_dynamic_info (main_map, false, false);
 
+      /* If the main map is libc.so, update the base namespace to
+	 refer to this map.  If libc.so is loaded later, this happens
+	 in _dl_map_object_from_fd.  */
+      if (main_map->l_info[DT_SONAME] != NULL
+	  && (strcmp (((const char *) D_PTR (main_map, l_info[DT_STRTAB])
+		      + main_map->l_info[DT_SONAME]->d_un.d_val), LIBC_SO)
+	      == 0))
+	GL(dl_ns)[LM_ID_BASE].libc_map = main_map;
+
       /* Set up our cache of pointers into the hash table.  */
       _dl_setup_hash (main_map);
     }
@@ -2377,8 +2386,7 @@ dl_main (const ElfW(Phdr) *phdr,
   /* Relocation is complete.  Perform early libc initialization.  This
      is the initial libc, even if audit modules have been loaded with
      other libcs.  */
-  if (GL(dl_ns)[LM_ID_BASE].libc_map != NULL)
-    GL(dl_ns)[LM_ID_BASE].libc_map_early_init (true);
+  _dl_call_libc_early_init (GL(dl_ns)[LM_ID_BASE].libc_map, true);
 
   /* Do any necessary cleanups for the startup OS interface code.
      We do these now so that no calls are made after rtld re-relocation
diff --git a/manual/install.texi b/manual/install.texi
index 6d43599a47..c775005581 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -144,15 +144,6 @@ dynamic linker diagnostics to run on CPUs which are not compatible with
 the rest of @theglibc{}, for example, due to compiler flags which target
 a later instruction set architecture (ISA).
 
-@item --with-extra-version-id=@var{string}
-Use @var{string} as part of the fingerprint that is used by the dynamic
-linker to detect an incompatible version of @file{libc.so}.  For
-example, @var{string} could be the full package version and release
-string used by a distribution build of @theglibc{}.  This way,
-concurrent process creation during a package update will fail with an
-error message, @emph{ld.so/libc.so mismatch detected (upgrade in
-progress?)}, rather than crashing mysteriously.
-
 @item --with-timeoutfactor=@var{NUM}
 Specify an integer @var{NUM} to scale the timeout of test programs.
 This factor can be changed at run time using @env{TIMEOUTFACTOR}
diff --git a/scripts/libc_early_init_name.py b/scripts/libc_early_init_name.py
deleted file mode 100644
index a56c2008f3..0000000000
--- a/scripts/libc_early_init_name.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/python3
-# Compute the hash-based name of the __libc_early_init function.
-# Copyright (C) 2022 Free Software Foundation, Inc.
-# This file is part of the GNU C Library.
-#
-# The GNU C Library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# The GNU C Library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with the GNU C Library; if not, see
-# <https://www.gnu.org/licenses/>.
-
-"""Compute the name of the __libc_early_init function, which is used
-as a protocol version marker between ld.so and libc.so.
-
-The name contains a hash suffix, and the hash changes if certain key
-files in the source tree change.  Distributions can also configure
-with --with-extra-version-id, to make the computed hash dependent on
-the package version.
-
-"""
-
-import argparse
-import hashlib
-import os
-import string
-import sys
-
-def gnu_hash(s):
-    """Computes the GNU hash of the string."""
-    h = 5381
-    for ch in s:
-        if type(ch) is not int:
-            ch = ord(ch)
-        h = (h * 33 + ch) & 0xffffffff
-    return h
-
-# Parse the command line.
-parser = argparse.ArgumentParser(description=__doc__)
-parser.add_argument('--output', metavar='PATH',
-                    help='path to header file this tool generates')
-parser.add_argument('--extra-version-id', metavar='ID',
-                    help='extra string to influence hash computation')
-parser.add_argument('inputs', metavar='PATH', nargs='*',
-                    help='files whose contents influences the generated hash')
-opts = parser.parse_args()
-
-# Obtain the blobs that affect the generated hash.
-blobs = [(opts.extra_version_id or '').encode('UTF-8')]
-for path in opts.inputs:
-    with open(path, 'rb') as inp:
-        blobs.append(inp.read())
-
-# Hash the file boundaries.
-md = hashlib.sha256()
-md.update(repr([len(blob) for blob in blobs]).encode('UTF-8'))
-
-# And then hash the file contents.  Do not hash the paths, to avoid
-# impacting reproducibility.
-for blob in blobs:
-    md.update(blob)
-
-# These are the bits used to compute the suffix.
-derived_bits = int.from_bytes(md.digest(), byteorder='big', signed=False)
-
-# These digits are used in the suffix (should result in base-62 encoding).
-# They must be valid in C identifiers.
-digits = string.digits + string.ascii_letters
-
-# Generate eight digits as a suffix.  They should provide enough
-# uniqueness (47.6 bits).
-name = '__libc_early_init_'
-for n in range(8):
-    name += digits[derived_bits % len(digits)]
-    derived_bits //= len(digits)
-
-# Write the output file.
-with open(opts.output, 'w') if opts.output else sys.stdout as out:
-    out.write('#define LIBC_EARLY_INIT_NAME {}\n'.format(name))
-    out.write('#define LIBC_EARLY_INIT_NAME_STRING "{}"\n'.format(name))
-    out.write('#define LIBC_EARLY_INIT_GNU_HASH {}\n'.format(
-        gnu_hash(name)))
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 275dbc95ce..050a3032de 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -333,10 +333,6 @@ struct rtld_global
        its link map.  */
     struct link_map *libc_map;
 
-    /* __libc_early_init function in libc_map.  Initialized at the
-       same time as libc_map.  */
-    void (*libc_map_early_init) (_Bool);
-
     /* Search table for unique objects.  */
     struct unique_sym_table
     {