[4/4] Add --disable-major-minor-libraries configure option

Message ID 476bfc2e0c41a91a37d945ae2af29e931801b0f7.1623237082.git.fweimer@redhat.com
State Superseded
Headers
Series Add --disable-major-minor-libraries configure option |

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent

Commit Message

Florian Weimer June 9, 2021, 11:16 a.m. UTC
  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(-)
  

Comments

Joseph Myers June 9, 2021, 4:03 p.m. UTC | #1
This needs a NEWS entry.
  
Florian Weimer June 9, 2021, 5:09 p.m. UTC | #2
* 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
  
Joseph Myers June 9, 2021, 5:28 p.m. UTC | #3
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.
  

Patch

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