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

Message ID 6d6f77fc251774d14246de794eea86e1da291d1c.1574945909.git.fweimer@redhat.com
State Superseded
Headers

Commit Message

Florian Weimer Nov. 28, 2019, 1:01 p.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.

I verified that by default, the install tree is the same as before
on x86_64-linux-gnu except for the changes in the manual.
---
 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

Florian Weimer Dec. 3, 2019, 2:39 p.m. UTC | #1
* Florian Weimer:

> 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.
>
> I verified that by default, the install tree is the same as before
> on x86_64-linux-gnu except for the changes in the manual.

This needs an update for ldconfig:

      /* Does this file look like a shared library or is it a hwcap
	 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)
	  && (direntry->d_type == DT_REG
	      || !is_hwcap_platform (direntry->d_name)))
	continue;

On some architectures, the loader no longer starts with ld- after this
change.

Thanks,
Florian
  

Patch

diff --git a/INSTALL b/INSTALL
index 392537cc5c..6d61f396ac 100644
--- a/INSTALL
+++ b/INSTALL
@@ -181,6 +181,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 fae71aa287..89b776d88c 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 bf6ffee186..032e6441b2 100644
--- a/Makerules
+++ b/Makerules
@@ -991,6 +991,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
@@ -998,7 +1006,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.
@@ -1051,6 +1059,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)
@@ -1060,6 +1069,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
@@ -1134,6 +1148,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);
@@ -1148,6 +1163,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 2fed3da773..ad48e54754 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@
 output-format = @libc_cv_output_format@
diff --git a/configure b/configure
index 2f44b66656..808fa8cd3d 100755
--- a/configure
+++ b/configure
@@ -682,6 +682,7 @@  experimental_malloc
 enable_werror
 all_warnings
 force_install
+major_minor_libraries
 bindnow
 hardcoded_path_in_tests
 enable_timezone_tools
@@ -776,6 +777,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
@@ -1441,6 +1443,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
@@ -3463,6 +3469,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 e69c88c543..c374eea065 100644
--- a/configure.ac
+++ b/configure.ac
@@ -251,6 +251,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],
 	      AC_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 305bed2d38..e3e898b1cc 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -553,6 +553,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)
@@ -562,11 +563,16 @@  $(inst_rtlddir)/$(rtld-installed-name): \
   $(inst_slibdir)/libc-$(version).so
 	$(make-target-directory)
 	$(make-shlib-link)
+else # !$(major-minor-libraries)
+$(inst_slibdir)/$(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)
 
 
 ldd-rewrite = -e 's%@RTLD@%$(rtlddir)/$(rtld-installed-name)%g' \
diff --git a/manual/install.texi b/manual/install.texi
index b2d569ac5a..d98f026f4a 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -209,6 +209,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