public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Add --disable-major-minor-libraries configure option
@ 2021-06-09 11:15 Florian Weimer
  2021-06-09 11:16 ` [PATCH 1/4] nptl_db: Install libthread_db under a regular implementation name Florian Weimer
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Florian Weimer @ 2021-06-09 11:15 UTC (permalink / raw)
  To: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 2509 bytes --]

This is a repost of an older patch series.  RPM-based distributions tend
to have issues around glibc downgrades across major glibc versions
because RPM deletes removed files very later, after the transaction is
complete.  This can result in a broken system because if ldconfig runs
after the downgraded glibc has been unpacked, it will put the newer
glibc's DSOs in to the ld.so cache, which are generally incompatible
with the downgraded dynamic loader.

The name-based DSO recognition patch is new.  Originally, I went with a
fancy Python script to gather ld.so names, but then I saw that only two
new patterns are required for generic detection.  The patterns are quite
specific, so I wrote a _dl_is_dso function instead of a table.  I'm
attaching the Python script for posterity in case it is useful for
something else.

I fixed a cut-and-past error in elf/Makefile which broke targets like
aarch64-linux-gnu and s390x-gnu-linux, where $(inst_slibdir) and
$(inst_rtlddir) are distinct.

My preference would be to avoid the new configure option and just drop
the versions unconditionally, but I'm worried that it's difficult to
obtain consensus around that.  My patch rebased cleanly over 18 months
of development, so there seems to be little varience in these Makefile
parts, so I don't think we need new build-many-glibcs.py targets for
this configuration.  I'm going to switch Fedora rawhide to it, so we get
some regular testing of these configurations anyway.

Tested on i686-linux-gnu, x86_64-linux-gnu; built with
build-many-glibcs.py.  Both with and without
--disable-major-minor-libraries.

Thanks,
Florian


Florian Weimer (4):
  nptl_db: Install libthread_db under a regular implementation name
  Makerules: Remove lib-version, $(subdir-version)
  elf: Generalize name-based DSO recognition in ldconfig
  Add --disable-major-minor-libraries configure option

 INSTALL             | 10 ++++++++++
 Makefile            |  4 +++-
 Makerules           | 38 ++++++++++++++++++++++----------------
 config.make.in      |  1 +
 configure           | 15 +++++++++++++++
 configure.ac        |  7 +++++++
 elf/Makefile        | 10 ++++++++--
 elf/dl-is_dso.h     | 33 +++++++++++++++++++++++++++++++++
 elf/ldconfig.c      |  5 ++---
 elf/tst-dl-is_dso.c | 35 +++++++++++++++++++++++++++++++++++
 manual/install.texi |  9 +++++++++
 nptl_db/Makefile    |  2 --
 12 files changed, 145 insertions(+), 24 deletions(-)
 create mode 100644 elf/dl-is_dso.h
 create mode 100644 elf/tst-dl-is_dso.c

-- 
2.31.1


[-- Attachment #2: gather-rtld-names.py --]
[-- Type: text/plain, Size: 4376 bytes --]

#!/usr/bin/python3
# Gather the names of all dynamic linkers in the glibc source tree.
# Copyright (C) 2021 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/>.

"""Gather dynamic linker names.

This script scans the glibc source tree for shlib-versions files and
extracts the dynamic linker name from them.  I writes a header file
which defines an RTLD_ALL_NAMES macro.

"""

import argparse
import os
import re
import sys

# The dynamic linker name is optionally followed by a symbol version
# baseline.
RE_LD = re.compile(r'^ld=(\S+)(?:$|\s)')

def get_rtld_name(path):
    """Extract the ld= line from the file at PATH and return the ld.so name."""
    with open(path) as inp:
        for line in inp:
            match = RE_LD.match(line)
            if match is not None:
                rtld_name, = match.groups()
                if not rtld_name:
                    sys.stderr.write('{}: error: invalid rtld name: {!r}\n'
                                     .format(path, line))
                    sys.exit(1)
                return rtld_name
    # Nothing found.  Use the default.
    return None

def write_deps(directories, files, deps, output):
    """Write makefile dependency information for the file OUTPUT to DEPS."""
    with open(deps, 'w') as outp:
        outp.write(output)
        outp.write(': \\\n')

        for entry in directories + files:
            outp.write('  ')
            outp.write(entry)
            outp.write(' \\\n')
        outp.write('\n')

def write_output(rtld_names, path):
    """Writes a header file with the names list to PATH."""
    with open(path, 'w') as outp:
        outp.write('/* This file is automatically generated by ')
        our_name = os.path.basename(__file__)
        outp.write(our_name)
        outp.write('.\n   Do not edit.  */\n\n')

        outp.write('#define RTLD_ALL_NAMES \\\n')
        for name in rtld_names:
            outp.write('  "')
            outp.write(name)
            outp.write('\\0" \\\n')
        # An empty string terminates the list.
        outp.write('  ""\n')

def main():
    """The main entry point."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--deps',
                        help='Dependency information for make',
                        type=str, required=True)
    parser.add_argument('--root',
                        help='Root directory of the source tree',
                        type=str, required=True)
    parser.add_argument('--output',
                        help='Generated source file with the ',
                        type=str, required=True)
    opts = parser.parse_args(sys.argv[1:])

    # The name of the file we are looking for.

    shlib_versions = 'shlib-versions'

    # This is used to generate directory dependencies, so that newly
    # added shlib-versions files will be found.
    directories = []

    # The default file does not live in a sysdeps subdirectory.
    files = [os.path.join(opts.root, shlib_versions)]

    # More files come from the sysdeps subdirectory.
    for dirpath, dirnames, filenames in os.walk(
            os.path.join(opts.root, 'sysdeps')):
        if shlib_versions in filenames:
            files.append(os.path.join(dirpath, shlib_versions))
        else:
            directories.append(dirpath)

    # Normalize the generated output.
    directories.sort()
    files.sort()
    write_deps(directories, files, opts.deps, opts.output)

    rtld_names = set()
    for path in files:
        name = get_rtld_name(path)
        if name is not None:
            rtld_names.add(name)

    write_output(sorted(rtld_names), opts.output)

if __name__ == "__main__":
    main()

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/4] nptl_db: Install libthread_db under a regular implementation name
  2021-06-09 11:15 [PATCH 0/4] Add --disable-major-minor-libraries configure option Florian Weimer
@ 2021-06-09 11:16 ` Florian Weimer
  2021-06-09 11:16 ` [PATCH 2/4] Makerules: Remove lib-version, $(subdir-version) Florian Weimer
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Florian Weimer @ 2021-06-09 11:16 UTC (permalink / raw)
  To: libc-alpha

Currently, the name is always libthread_db-1.0.so.  It does not change
with the glibc version, like the other libraries.

GDB hard-codes libthread_db.so.1 (the soname), so this change does not
affect loading libthread_db.

Tested on x86_64-linux-gnu, in an environment where the nptl GDB tests
actually run.
---
 nptl_db/Makefile | 2 --
 1 file changed, 2 deletions(-)

diff --git a/nptl_db/Makefile b/nptl_db/Makefile
index ea721c1dcf..1f79c018a1 100644
--- a/nptl_db/Makefile
+++ b/nptl_db/Makefile
@@ -21,8 +21,6 @@ subdir          := nptl_db
 
 include ../Makeconfig
 
-nptl_db-version = 1.0
-
 extra-libs = libthread_db
 extra-libs-others := $(extra-libs)
 
-- 
2.31.1



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 2/4] Makerules: Remove lib-version, $(subdir-version)
  2021-06-09 11:15 [PATCH 0/4] Add --disable-major-minor-libraries configure option Florian Weimer
  2021-06-09 11:16 ` [PATCH 1/4] nptl_db: Install libthread_db under a regular implementation name Florian Weimer
@ 2021-06-09 11:16 ` Florian Weimer
  2021-06-09 11:16 ` [PATCH 3/4] elf: Generalize name-based DSO recognition in ldconfig Florian Weimer
  2021-06-09 11:16 ` [PATCH 4/4] Add --disable-major-minor-libraries configure option Florian Weimer
  3 siblings, 0 replies; 10+ messages in thread
From: Florian Weimer @ 2021-06-09 11:16 UTC (permalink / raw)
  To: libc-alpha

Also clarify that the “versioned” term refers to the soname, not the glibc
version (which also ends up in the installed file name).

I verified on x86_64-linux-gnu that “make install” produces the same
files.
---
 Makerules | 26 ++++----------------------
 1 file changed, 4 insertions(+), 22 deletions(-)

diff --git a/Makerules b/Makerules
index ca9885436e..d3f29d0b89 100644
--- a/Makerules
+++ b/Makerules
@@ -982,22 +982,21 @@ install-lib.so := $(filter %.so,$(install-lib:%_pic.a=%.so))
 install-lib := $(filter-out %.so %_pic.a,$(install-lib))
 
 ifeq (yes,$(build-shared))
-# Find which .so's have versions.
+# Find which .so's have a version number in their soname.
 versioned := $(strip $(foreach so,$(install-lib.so),\
 			       $(patsubst %,$(so),$($(so)-version))))
 
 install-lib.so-versioned := $(filter $(versioned), $(install-lib.so))
 install-lib.so-unversioned := $(filter-out $(versioned), $(install-lib.so))
 
-# For versioned libraries, we install three files:
+# For libraries whose soname have version numbers, we install three files:
 #	$(inst_libdir)/libfoo.so	-- for linking, symlink or ld script
 #	$(inst_slibdir)/libfoo.so.NN	-- for loading by SONAME, symlink
 #	$(inst_slibdir)/libfoo-X.Y.Z.so -- the real shared object file
-lib-version := $(firstword $($(subdir)-version) $(version))
 install-lib-nosubdir: $(install-lib.so-unversioned:%=$(inst_slibdir)/%) \
 		      $(foreach L,$(install-lib.so-versioned),\
 				$(inst_libdir)/$L \
-				$(inst_slibdir)/$(L:.so=)-$(lib-version).so \
+				$(inst_slibdir)/$(L:.so=)-$(version).so \
 				$(inst_slibdir)/$L$($L-version))
 
 # Install all the unversioned shared libraries.
@@ -1125,7 +1124,6 @@ include $(o-iterator)
 
 generated += $(foreach o,$(versioned),$o$($o-version))
 
-ifeq (,$($(subdir)-version))
 define o-iterator-doit
 $(inst_slibdir)/$o$($o-version): $(inst_slibdir)/$(o:.so=)-$(version).so \
 				 $(+force);
@@ -1140,23 +1138,7 @@ $(inst_slibdir)/$(o:.so=)-$(version).so: $(objpfx)$o $(+force);
 endef
 object-suffixes-left := $(versioned)
 include $(o-iterator)
-else
-define o-iterator-doit
-$(inst_slibdir)/$o$($o-version): \
-  $(inst_slibdir)/$(o:.so=)-$($(subdir)-version).so $(+force);
-	$$(make-shlib-link)
-endef
-object-suffixes-left := $(versioned)
-include $(o-iterator)
-
-define o-iterator-doit
-$(inst_slibdir)/$(o:.so=)-$($(subdir)-version).so: $(objpfx)$o $(+force);
-	$$(do-install-program)
-endef
-object-suffixes-left := $(versioned)
-include $(o-iterator)
-endif
-endif
+endif # ifneq (,$(versioned))
 
 define do-install-so
 $(do-install-program)
-- 
2.31.1



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 3/4] elf: Generalize name-based DSO recognition in ldconfig
  2021-06-09 11:15 [PATCH 0/4] Add --disable-major-minor-libraries configure option Florian Weimer
  2021-06-09 11:16 ` [PATCH 1/4] nptl_db: Install libthread_db under a regular implementation name Florian Weimer
  2021-06-09 11:16 ` [PATCH 2/4] Makerules: Remove lib-version, $(subdir-version) Florian Weimer
@ 2021-06-09 11:16 ` Florian Weimer
  2021-06-09 11:16 ` [PATCH 4/4] Add --disable-major-minor-libraries configure option Florian Weimer
  3 siblings, 0 replies; 10+ messages in thread
From: Florian Weimer @ 2021-06-09 11:16 UTC (permalink / raw)
  To: libc-alpha

This introduces <dl-is_dso.h> and the _dl_is_dso function.  A
test ensures that the official names of libc.so, ld.so, and their
versioned names are recognized.
---
 elf/Makefile        |  2 +-
 elf/dl-is_dso.h     | 33 +++++++++++++++++++++++++++++++++
 elf/ldconfig.c      |  5 ++---
 elf/tst-dl-is_dso.c | 35 +++++++++++++++++++++++++++++++++++
 4 files changed, 71 insertions(+), 4 deletions(-)
 create mode 100644 elf/dl-is_dso.h
 create mode 100644 elf/tst-dl-is_dso.c

diff --git a/elf/Makefile b/elf/Makefile
index e9788d3d4f..5389c35536 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -223,7 +223,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
 	 tst-single_threaded tst-single_threaded-pthread \
 	 tst-tls-ie tst-tls-ie-dlmopen argv0test \
 	 tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \
-	 tst-tls20 tst-tls21 tst-dlmopen-dlerror
+	 tst-tls20 tst-tls21 tst-dlmopen-dlerror tst-dl-is_dso
 #	 reldep9
 tests-internal += loadtest unload unload2 circleload1 \
 	 neededtest neededtest2 neededtest3 neededtest4 \
diff --git a/elf/dl-is_dso.h b/elf/dl-is_dso.h
new file mode 100644
index 0000000000..94e00966a1
--- /dev/null
+++ b/elf/dl-is_dso.h
@@ -0,0 +1,33 @@
+/* Heuristic for recognizing DSO file names.
+   Copyright (C) 2021 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/>.  */
+
+#include <stdbool.h>
+#include <string.h>
+
+/* Returns true if the file name looks like a DSO name.  */
+static bool
+_dl_is_dso (const char *name)
+{
+  /* Recognize lib*.so*, ld-*.so*, ld.so.*, ld64.so.*.  ld-*.so*
+     matches both platform dynamic linker names like ld-linux.so.2,
+     and versioned dynamic loader names like ld-2.12.so.  */
+  return (((strncmp (name, "lib", 3) == 0 || strncmp (name, "ld-", 3) == 0)
+           && strstr (name, ".so") != NULL)
+          || strncmp (name, "ld.so.", 6) == 0
+          || strncmp (name, "ld64.so.", 8) == 0);
+}
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
index 96bf7700b2..1037e8d0cf 100644
--- a/elf/ldconfig.c
+++ b/elf/ldconfig.c
@@ -43,6 +43,7 @@
 #include <ldconfig.h>
 #include <dl-cache.h>
 #include <dl-hwcaps.h>
+#include <dl-is_dso.h>
 
 #include <dl-procinfo.h>
 
@@ -842,9 +843,7 @@ search_dir (const struct dir_entry *entry)
 	 subdirectory (if not already processing a glibc-hwcaps
 	 subdirectory)?  The dynamic linker is also considered as
 	 shared library.  */
-      if (((strncmp (direntry->d_name, "lib", 3) != 0
-	    && strncmp (direntry->d_name, "ld-", 3) != 0)
-	   || strstr (direntry->d_name, ".so") == NULL)
+      if (!_dl_is_dso (direntry->d_name)
 	  && (direntry->d_type == DT_REG
 	      || (entry->hwcaps == NULL
 		  && !is_hwcap_platform (direntry->d_name))))
diff --git a/elf/tst-dl-is_dso.c b/elf/tst-dl-is_dso.c
new file mode 100644
index 0000000000..48d2cc9fbe
--- /dev/null
+++ b/elf/tst-dl-is_dso.c
@@ -0,0 +1,35 @@
+/* Test heuristic for recognizing DSO file names.
+   Copyright (C) 2021 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/>.  */
+
+#include <dl-is_dso.h>
+#include <gnu/lib-names.h>
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+  /* Official ABI names.  */
+  TEST_VERIFY (_dl_is_dso (LIBC_SO));
+  TEST_VERIFY (_dl_is_dso (LD_SO));
+  /* Version-based names.  The version number does not matter.  */
+  TEST_VERIFY (_dl_is_dso ("libc-2.12.so"));
+  TEST_VERIFY (_dl_is_dso ("ld-2.12.so"));
+  return 0;
+}
+
+#include <support/test-driver.c>
-- 
2.31.1



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 4/4] Add --disable-major-minor-libraries configure option
  2021-06-09 11:15 [PATCH 0/4] Add --disable-major-minor-libraries configure option Florian Weimer
                   ` (2 preceding siblings ...)
  2021-06-09 11:16 ` [PATCH 3/4] elf: Generalize name-based DSO recognition in ldconfig Florian Weimer
@ 2021-06-09 11:16 ` Florian Weimer
  2021-06-09 16:03   ` Joseph Myers
  3 siblings, 1 reply; 10+ messages in thread
From: Florian Weimer @ 2021-06-09 11:16 UTC (permalink / raw)
  To: libc-alpha

This option can be used to increase compatibility with package managers.
The name was choosen to avoid confusion with all the different versions
(glibc release, soname versions, symbol versions).

This patch makes all uses of -$(version).so conditional on the new
$(major-minor-libraries) flag.  The alternative install targets write
the implementation DSOs directly to the locations determined by their
sonames, skipping the creation of an intermediate symbolic link.

install-symbolic-link in Makerules is updated not to require the
$(symbolic-link-list) file because it may not exist in
--disable-major-minor-libraries mode.
---
 INSTALL             | 10 ++++++++++
 Makefile            |  4 +++-
 Makerules           | 26 +++++++++++++++++++++++++-
 config.make.in      |  1 +
 configure           | 15 +++++++++++++++
 configure.ac        |  7 +++++++
 elf/Makefile        |  8 +++++++-
 manual/install.texi |  9 +++++++++
 8 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/INSTALL b/INSTALL
index bc761ab98b..ed5f66489b 100644
--- a/INSTALL
+++ b/INSTALL
@@ -199,6 +199,16 @@ if 'CFLAGS' is specified it must enable optimization.  For example:
      RELRO and a read-only global offset table (GOT), at the cost of
      slightly increased program load times.
 
+'--disable-major-minor-libraries'
+     Do not install shared objects under file names that contain the
+     major and minor version of the GNU C Library.  By default, such
+     names are used, and the names defined by the ABI are provided as
+     symbolic links only.  This causes problems with certain package
+     managers during library upgrades and (in particular) downgrades, so
+     this option can be used to install these shared objects directly
+     under their ABI-defined names, without an additional indirection
+     via symbolic links.
+
 '--enable-pt_chown'
      The file 'pt_chown' is a helper binary for 'grantpt' (*note
      Pseudo-Terminals: Allocation.) that is installed setuid root to fix
diff --git a/Makefile b/Makefile
index 242d36de91..4cf422adce 100644
--- a/Makefile
+++ b/Makefile
@@ -112,7 +112,9 @@ ifeq (yes,$(build-shared))
 install: install-symbolic-link
 .PHONY: install-symbolic-link
 install-symbolic-link: subdir_install
-	$(symbolic-link-prog) $(symbolic-link-list)
+	if test -e $(symbolic-link-list) ; then \
+	  $(symbolic-link-prog) $(symbolic-link-list); \
+	fi
 	rm -f $(symbolic-link-list)
 
 install:
diff --git a/Makerules b/Makerules
index d3f29d0b89..162b92a4c2 100644
--- a/Makerules
+++ b/Makerules
@@ -989,6 +989,14 @@ versioned := $(strip $(foreach so,$(install-lib.so),\
 install-lib.so-versioned := $(filter $(versioned), $(install-lib.so))
 install-lib.so-unversioned := $(filter-out $(versioned), $(install-lib.so))
 
+# $(install-major-minor-libraries) is used within install-lib-nosubdir
+# to trigger installation of the actual implementation file.
+ifeq (yes,$(major-minor-libraries))
+install-major-minor-libraries = $(inst_slibdir)/$(L:.so=)-$(version).so
+else
+install-major-minor-libraries =
+endif
+
 # For libraries whose soname have version numbers, we install three files:
 #	$(inst_libdir)/libfoo.so	-- for linking, symlink or ld script
 #	$(inst_slibdir)/libfoo.so.NN	-- for loading by SONAME, symlink
@@ -996,7 +1004,7 @@ install-lib.so-unversioned := $(filter-out $(versioned), $(install-lib.so))
 install-lib-nosubdir: $(install-lib.so-unversioned:%=$(inst_slibdir)/%) \
 		      $(foreach L,$(install-lib.so-versioned),\
 				$(inst_libdir)/$L \
-				$(inst_slibdir)/$(L:.so=)-$(version).so \
+				$(install-major-minor-libraries) \
 				$(inst_slibdir)/$L$($L-version))
 
 # Install all the unversioned shared libraries.
@@ -1049,6 +1057,7 @@ endef
 endif
 
 ifdef libc.so-version
+ifeq (yes,$(major-minor-libraries))
 # For a library specified to be version N, install three files:
 # libc.so	->	libc.so.N	(e.g. libc.so.6)
 # libc.so.6	->	libc-VERSION.so	(e.g. libc-1.10.so)
@@ -1058,6 +1067,11 @@ $(inst_slibdir)/libc.so$(libc.so-version): $(inst_slibdir)/libc-$(version).so \
 	$(make-shlib-link)
 $(inst_slibdir)/libc-$(version).so: $(common-objpfx)libc.so $(+force)
 	$(do-install-program)
+else # !$(major-minor-libraries)
+$(inst_slibdir)/libc.so$(libc.so-version): $(common-objpfx)libc.so $(+force)
+	$(do-install-program)
+endif # !$(major-minor-libraries)
+
 install: $(inst_slibdir)/libc.so$(libc.so-version)
 
 # This fragment of linker script gives the OUTPUT_FORMAT statement
@@ -1124,6 +1138,7 @@ include $(o-iterator)
 
 generated += $(foreach o,$(versioned),$o$($o-version))
 
+ifeq (yes,$(major-minor-libraries))
 define o-iterator-doit
 $(inst_slibdir)/$o$($o-version): $(inst_slibdir)/$(o:.so=)-$(version).so \
 				 $(+force);
@@ -1138,6 +1153,15 @@ $(inst_slibdir)/$(o:.so=)-$(version).so: $(objpfx)$o $(+force);
 endef
 object-suffixes-left := $(versioned)
 include $(o-iterator)
+
+else # !$(major-minor-libraries)
+define o-iterator-doit
+$(inst_slibdir)/$o$($o-version): $(objpfx)$o $(+force);
+	$$(do-install-program)
+endef
+object-suffixes-left := $(versioned)
+include $(o-iterator)
+endif # !$(major-minor-libraries)
 endif # ifneq (,$(versioned))
 
 define do-install-so
diff --git a/config.make.in b/config.make.in
index cbf59114b0..55a8351dd2 100644
--- a/config.make.in
+++ b/config.make.in
@@ -71,6 +71,7 @@ have-libcap = @have_libcap@
 have-cc-with-libunwind = @libc_cv_cc_with_libunwind@
 fno-unit-at-a-time = @fno_unit_at_a_time@
 bind-now = @bindnow@
+major-minor-libraries = @major_minor_libraries@
 have-hash-style = @libc_cv_hashstyle@
 use-default-link = @use_default_link@
 have-cxx-thread_local = @libc_cv_cxx_thread_local@
diff --git a/configure b/configure
index a86bcf7671..cb98b4c047 100755
--- a/configure
+++ b/configure
@@ -681,6 +681,7 @@ experimental_malloc
 enable_werror
 all_warnings
 force_install
+major_minor_libraries
 bindnow
 hardcoded_path_in_tests
 enable_timezone_tools
@@ -774,6 +775,7 @@ enable_hidden_plt
 enable_bind_now
 enable_stack_protector
 enable_static_nss
+enable_major_minor_libraries
 enable_force_install
 enable_maintainer_mode
 enable_kernel
@@ -1435,6 +1437,10 @@ Optional Features:
                           Use -fstack-protector[-all|-strong] to detect glibc
                           buffer overflows
   --enable-static-nss     build static NSS modules [default=no]
+  --enable-major-minor-libraries
+                          install most shared objects under names based on the
+                          glibc version, with symbolic links to them
+                          [default=yes]
   --disable-force-install don't force installation of files from this package,
                           even if they are older than the installed files
   --enable-maintainer-mode
@@ -3480,6 +3486,15 @@ if test x"$static_nss" = xyes || test x"$shared" = xno; then
 
 fi
 
+# Check whether --enable-major-minor-libraries was given.
+if test "${enable_major_minor_libraries+set}" = set; then :
+  enableval=$enable_major_minor_libraries; major_minor_libraries=$enableval
+else
+  major_minor_libraries=yes
+fi
+
+
+
 # Check whether --enable-force-install was given.
 if test "${enable_force_install+set}" = set; then :
   enableval=$enable_force_install; force_install=$enableval
diff --git a/configure.ac b/configure.ac
index f2588f394f..91d54e6926 100644
--- a/configure.ac
+++ b/configure.ac
@@ -242,6 +242,13 @@ if test x"$static_nss" = xyes || test x"$shared" = xno; then
   AC_DEFINE(DO_STATIC_NSS)
 fi
 
+AC_ARG_ENABLE([major-minor-libraries],
+	AC_HELP_STRING([--enable-major-minor-libraries],
+	[install most shared objects under names based on the glibc version, with symbolic links to them  @<:@default=yes@:>@]),
+	[major_minor_libraries=$enableval],
+	[major_minor_libraries=yes])
+AC_SUBST(major_minor_libraries)
+
 AC_ARG_ENABLE([force-install],
 	      AS_HELP_STRING([--disable-force-install],
 			     [don't force installation of files from this package, even if they are older than the installed files]),
diff --git a/elf/Makefile b/elf/Makefile
index 5389c35536..3211dbfd64 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -628,6 +628,7 @@ $(objpfx)trusted-dirs.st: Makefile $(..)Makeconfig
 CPPFLAGS-dl-load.c += -I$(objpfx). -I$(csu-objpfx).
 
 ifeq (yes,$(build-shared))
+ifeq (yes,$(major-minor-libraries))
 $(inst_slibdir)/$(rtld-version-installed-name): $(objpfx)ld.so $(+force)
 	$(make-target-directory)
 	$(do-install-program)
@@ -637,11 +638,16 @@ $(inst_rtlddir)/$(rtld-installed-name): \
   $(inst_slibdir)/libc-$(version).so
 	$(make-target-directory)
 	$(make-shlib-link)
+else # !$(major-minor-libraries)
+$(inst_rtlddir)/$(rtld-installed-name): $(objpfx)ld.so $(+force)
+	$(make-target-directory)
+	$(do-install-program)
+endif # !$(major-minor-libraries)
 
 # Special target called by parent to install just the dynamic linker.
 .PHONY: ldso_install
 ldso_install: $(inst_rtlddir)/$(rtld-installed-name)
-endif
+endif # $(build-shared)
 
 
 # Workarounds for ${exec_prefix} expansion in configure variables.
diff --git a/manual/install.texi b/manual/install.texi
index f1d858fb78..3e0ae46285 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -226,6 +226,15 @@ provides additional security hardening because it enables full RELRO
 and a read-only global offset table (GOT), at the cost of slightly
 increased program load times.
 
+@item --disable-major-minor-libraries
+Do not install shared objects under file names that contain the major
+and minor version of @theglibc.  By default, such names are used, and
+the names defined by the ABI are provided as symbolic links only.  This
+causes problems with certain package managers during library upgrades
+and (in particular) downgrades, so this option can be used to install
+these shared objects directly under their ABI-defined names, without an
+additional indirection via symbolic links.
+
 @pindex pt_chown
 @findex grantpt
 @item --enable-pt_chown
-- 
2.31.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] Add --disable-major-minor-libraries configure option
  2021-06-09 11:16 ` [PATCH 4/4] Add --disable-major-minor-libraries configure option Florian Weimer
@ 2021-06-09 16:03   ` Joseph Myers
  2021-06-09 17:09     ` Florian Weimer
  0 siblings, 1 reply; 10+ messages in thread
From: Joseph Myers @ 2021-06-09 16:03 UTC (permalink / raw)
  To: Florian Weimer; +Cc: libc-alpha

This needs a NEWS entry.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] Add --disable-major-minor-libraries configure option
  2021-06-09 16:03   ` Joseph Myers
@ 2021-06-09 17:09     ` Florian Weimer
  2021-06-09 17:28       ` Joseph Myers
  0 siblings, 1 reply; 10+ messages in thread
From: Florian Weimer @ 2021-06-09 17:09 UTC (permalink / raw)
  To: Joseph Myers; +Cc: libc-alpha

* Joseph Myers:

> This needs a NEWS entry.

What about this?

* glibc can now be configured with the --disable-major-minor-libraries
  option.  In this case, the various shared objects that are part of
  glibc will be installed under their ABI sonames (such as libc.so.6)
  rather than version-specific file names (such as libc-2.34.so).  As
  before, by default, glibc installs them as version-specific file
  names, with the ABI sonames added as symbolic links.  The
  --disable-major-minor-libraries option enables safer downgrades with
  package managers which delete removed files very late, after invoking
  ldconfig.

Indepdently of the implementation of the patch, do you think this is
something that needs to be configurable, or can we remove versioned file
names altogether?

Thanks,
Florian


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/4] Add --disable-major-minor-libraries configure option
  2021-06-09 17:09     ` Florian Weimer
@ 2021-06-09 17:28       ` Joseph Myers
  0 siblings, 0 replies; 10+ messages in thread
From: Joseph Myers @ 2021-06-09 17:28 UTC (permalink / raw)
  To: Florian Weimer; +Cc: libc-alpha

On Wed, 9 Jun 2021, Florian Weimer via Libc-alpha wrote:

> * Joseph Myers:
> 
> > This needs a NEWS entry.
> 
> What about this?
> 
> * glibc can now be configured with the --disable-major-minor-libraries
>   option.  In this case, the various shared objects that are part of
>   glibc will be installed under their ABI sonames (such as libc.so.6)
>   rather than version-specific file names (such as libc-2.34.so).  As
>   before, by default, glibc installs them as version-specific file
>   names, with the ABI sonames added as symbolic links.  The
>   --disable-major-minor-libraries option enables safer downgrades with
>   package managers which delete removed files very late, after invoking
>   ldconfig.

That seems reasonable (if we have this option at all).

> Indepdently of the implementation of the patch, do you think this is
> something that needs to be configurable, or can we remove versioned file
> names altogether?

I don't know why we have the versioned file names, but my guess would be 
it was intended to help with downgrades after a non-package-manager 
installation directly into the root filesystem went wrong (someone could 
try to use sln to recover by linking back to the older-version files).

I don't think we should expect installation directly into the root 
filesystem by "make install" to work reliably anyway, let alone provide a 
downgrade mechanism, so I don't see the need to support versioned file 
names any more.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/4] Makerules: Remove lib-version, $(subdir-version)
  2021-06-10  8:23 ` [PATCH 2/4] Makerules: Remove lib-version, $(subdir-version) Florian Weimer
@ 2021-06-27 21:32   ` Carlos O'Donell
  0 siblings, 0 replies; 10+ messages in thread
From: Carlos O'Donell @ 2021-06-27 21:32 UTC (permalink / raw)
  To: Florian Weimer, libc-alpha

On 6/10/21 4:23 AM, Florian Weimer via Libc-alpha wrote:
> Also clarify that the “versioned” term refers to the soname, not the glibc
> version (which also ends up in the installed file name).

Right.

Tested on x86_64 and i686. No regressions. Installed files look good.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
 
> I verified on x86_64-linux-gnu that “make install” produces the same
> files.
> ---
>  Makerules | 26 ++++----------------------
>  1 file changed, 4 insertions(+), 22 deletions(-)
> 
> diff --git a/Makerules b/Makerules
> index ca9885436e..d3f29d0b89 100644
> --- a/Makerules
> +++ b/Makerules
> @@ -982,22 +982,21 @@ install-lib.so := $(filter %.so,$(install-lib:%_pic.a=%.so))
>  install-lib := $(filter-out %.so %_pic.a,$(install-lib))
>  
>  ifeq (yes,$(build-shared))
> -# Find which .so's have versions.
> +# Find which .so's have a version number in their soname.

OK.

>  versioned := $(strip $(foreach so,$(install-lib.so),\
>  			       $(patsubst %,$(so),$($(so)-version))))
>  
>  install-lib.so-versioned := $(filter $(versioned), $(install-lib.so))
>  install-lib.so-unversioned := $(filter-out $(versioned), $(install-lib.so))
>  
> -# For versioned libraries, we install three files:
> +# For libraries whose soname have version numbers, we install three files:

OK. Correct.

>  #	$(inst_libdir)/libfoo.so	-- for linking, symlink or ld script
>  #	$(inst_slibdir)/libfoo.so.NN	-- for loading by SONAME, symlink
>  #	$(inst_slibdir)/libfoo-X.Y.Z.so -- the real shared object file
> -lib-version := $(firstword $($(subdir)-version) $(version))

OK. Remove.

>  install-lib-nosubdir: $(install-lib.so-unversioned:%=$(inst_slibdir)/%) \
>  		      $(foreach L,$(install-lib.so-versioned),\
>  				$(inst_libdir)/$L \
> -				$(inst_slibdir)/$(L:.so=)-$(lib-version).so \
> +				$(inst_slibdir)/$(L:.so=)-$(version).so \

OK. This doesn't change anything. Cleanup.

>  				$(inst_slibdir)/$L$($L-version))
>  
>  # Install all the unversioned shared libraries.
> @@ -1125,7 +1124,6 @@ include $(o-iterator)
>  
>  generated += $(foreach o,$(versioned),$o$($o-version))
>  
> -ifeq (,$($(subdir)-version))

OK. Cleanup.

>  define o-iterator-doit
>  $(inst_slibdir)/$o$($o-version): $(inst_slibdir)/$(o:.so=)-$(version).so \
>  				 $(+force);
> @@ -1140,23 +1138,7 @@ $(inst_slibdir)/$(o:.so=)-$(version).so: $(objpfx)$o $(+force);
>  endef
>  object-suffixes-left := $(versioned)
>  include $(o-iterator)
> -else
> -define o-iterator-doit
> -$(inst_slibdir)/$o$($o-version): \
> -  $(inst_slibdir)/$(o:.so=)-$($(subdir)-version).so $(+force);
> -	$$(make-shlib-link)
> -endef
> -object-suffixes-left := $(versioned)
> -include $(o-iterator)
> -
> -define o-iterator-doit
> -$(inst_slibdir)/$(o:.so=)-$($(subdir)-version).so: $(objpfx)$o $(+force);
> -	$$(do-install-program)
> -endef
> -object-suffixes-left := $(versioned)
> -include $(o-iterator)
> -endif
> -endif
> +endif # ifneq (,$(versioned))

OK. Not needed.

>  
>  define do-install-so
>  $(do-install-program)
> 


-- 
Cheers,
Carlos.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 2/4] Makerules: Remove lib-version, $(subdir-version)
  2021-06-10  8:22 [PATCH 0/4] Do not install shared objects under versioned names Florian Weimer
@ 2021-06-10  8:23 ` Florian Weimer
  2021-06-27 21:32   ` Carlos O'Donell
  0 siblings, 1 reply; 10+ messages in thread
From: Florian Weimer @ 2021-06-10  8:23 UTC (permalink / raw)
  To: libc-alpha

Also clarify that the “versioned” term refers to the soname, not the glibc
version (which also ends up in the installed file name).

I verified on x86_64-linux-gnu that “make install” produces the same
files.
---
 Makerules | 26 ++++----------------------
 1 file changed, 4 insertions(+), 22 deletions(-)

diff --git a/Makerules b/Makerules
index ca9885436e..d3f29d0b89 100644
--- a/Makerules
+++ b/Makerules
@@ -982,22 +982,21 @@ install-lib.so := $(filter %.so,$(install-lib:%_pic.a=%.so))
 install-lib := $(filter-out %.so %_pic.a,$(install-lib))
 
 ifeq (yes,$(build-shared))
-# Find which .so's have versions.
+# Find which .so's have a version number in their soname.
 versioned := $(strip $(foreach so,$(install-lib.so),\
 			       $(patsubst %,$(so),$($(so)-version))))
 
 install-lib.so-versioned := $(filter $(versioned), $(install-lib.so))
 install-lib.so-unversioned := $(filter-out $(versioned), $(install-lib.so))
 
-# For versioned libraries, we install three files:
+# For libraries whose soname have version numbers, we install three files:
 #	$(inst_libdir)/libfoo.so	-- for linking, symlink or ld script
 #	$(inst_slibdir)/libfoo.so.NN	-- for loading by SONAME, symlink
 #	$(inst_slibdir)/libfoo-X.Y.Z.so -- the real shared object file
-lib-version := $(firstword $($(subdir)-version) $(version))
 install-lib-nosubdir: $(install-lib.so-unversioned:%=$(inst_slibdir)/%) \
 		      $(foreach L,$(install-lib.so-versioned),\
 				$(inst_libdir)/$L \
-				$(inst_slibdir)/$(L:.so=)-$(lib-version).so \
+				$(inst_slibdir)/$(L:.so=)-$(version).so \
 				$(inst_slibdir)/$L$($L-version))
 
 # Install all the unversioned shared libraries.
@@ -1125,7 +1124,6 @@ include $(o-iterator)
 
 generated += $(foreach o,$(versioned),$o$($o-version))
 
-ifeq (,$($(subdir)-version))
 define o-iterator-doit
 $(inst_slibdir)/$o$($o-version): $(inst_slibdir)/$(o:.so=)-$(version).so \
 				 $(+force);
@@ -1140,23 +1138,7 @@ $(inst_slibdir)/$(o:.so=)-$(version).so: $(objpfx)$o $(+force);
 endef
 object-suffixes-left := $(versioned)
 include $(o-iterator)
-else
-define o-iterator-doit
-$(inst_slibdir)/$o$($o-version): \
-  $(inst_slibdir)/$(o:.so=)-$($(subdir)-version).so $(+force);
-	$$(make-shlib-link)
-endef
-object-suffixes-left := $(versioned)
-include $(o-iterator)
-
-define o-iterator-doit
-$(inst_slibdir)/$(o:.so=)-$($(subdir)-version).so: $(objpfx)$o $(+force);
-	$$(do-install-program)
-endef
-object-suffixes-left := $(versioned)
-include $(o-iterator)
-endif
-endif
+endif # ifneq (,$(versioned))
 
 define do-install-so
 $(do-install-program)
-- 
2.31.1



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-06-27 21:32 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-09 11:15 [PATCH 0/4] Add --disable-major-minor-libraries configure option Florian Weimer
2021-06-09 11:16 ` [PATCH 1/4] nptl_db: Install libthread_db under a regular implementation name Florian Weimer
2021-06-09 11:16 ` [PATCH 2/4] Makerules: Remove lib-version, $(subdir-version) Florian Weimer
2021-06-09 11:16 ` [PATCH 3/4] elf: Generalize name-based DSO recognition in ldconfig Florian Weimer
2021-06-09 11:16 ` [PATCH 4/4] Add --disable-major-minor-libraries configure option Florian Weimer
2021-06-09 16:03   ` Joseph Myers
2021-06-09 17:09     ` Florian Weimer
2021-06-09 17:28       ` Joseph Myers
2021-06-10  8:22 [PATCH 0/4] Do not install shared objects under versioned names Florian Weimer
2021-06-10  8:23 ` [PATCH 2/4] Makerules: Remove lib-version, $(subdir-version) Florian Weimer
2021-06-27 21:32   ` Carlos O'Donell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).