[09/10] elf: Add facility to create stub DSOs in elf/stub-dsos

Message ID 4ea2bdaebef66c6646aa0f8df13b4108d7933b7d.1621347402.git.fweimer@redhat.com
State Dropped
Headers
Series nptl: Complete libpthread removal |

Checks

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

Commit Message

Florian Weimer May 18, 2021, 2:25 p.m. UTC
  And reference the elf/stub-dsos directory when linking installed
programs.
---
 Makeconfig     | 10 ++++++++--
 elf/Makefile   | 18 +++++++++++++++++-
 elf/lib-stub.S | 22 ++++++++++++++++++++++
 3 files changed, 47 insertions(+), 3 deletions(-)
 create mode 100644 elf/lib-stub.S
  

Comments

Adhemerval Zanella May 24, 2021, 6:24 p.m. UTC | #1
On 18/05/2021 11:25, Florian Weimer via Libc-alpha wrote:
> And reference the elf/stub-dsos directory when linking installed
> programs.

So if I understood correctly, this is to trigger an invalid runtime
to avoid linking against system GLIBC_PRIVATE symbols, right?

I am not sure I fully understand the lib-stub trick here, how
exactly the lib-stub is preventing the wrong linkage here? And why
is this required for the libpthread move (my feeling this is orthogonal
to the project).

> ---
>  Makeconfig     | 10 ++++++++--
>  elf/Makefile   | 18 +++++++++++++++++-
>  elf/lib-stub.S | 22 ++++++++++++++++++++++
>  3 files changed, 47 insertions(+), 3 deletions(-)
>  create mode 100644 elf/lib-stub.S
> 
> diff --git a/Makeconfig b/Makeconfig
> index 1d5e45926c..3ef71cc02b 100644
> --- a/Makeconfig
> +++ b/Makeconfig
> @@ -425,7 +425,8 @@ ifndef +link-pie
>  	     $(link-extra-libs)
>  +link-pie-after-libc = $(+postctorS) $(+postinit)
>  define +link-pie
> -$(CC) $(link-libc-rpath-link) $(+link-pie-before-libc) $(rtld-LDFLAGS) \
> +$(CC) $(link-libc-rpath-link)$(rpath-link-stubs) \
> +  $(+link-pie-before-libc) $(rtld-LDFLAGS) \
>    $(link-extra-flags) $(link-libc) $(+link-pie-after-libc)
>  $(call after-link,$@)
>  endef

Ok.

> @@ -487,7 +488,8 @@ else  # not build-pie-default
>  	      $(link-extra-libs)
>  +link-after-libc = $(+postctor) $(+postinit)
>  define +link
> -$(CC) $(link-libc-rpath-link) $(+link-before-libc) $(rtld-LDFLAGS) \
> +$(CC) $(link-libc-rpath-link)$(rpath-link-stubs) \
> +  $(+link-before-libc) $(rtld-LDFLAGS) \
>    $(link-extra-flags) $(link-libc) $(+link-after-libc)
>  $(call after-link,$@)
>  endef
> @@ -581,6 

Ok.

+583,10 @@ link-libc-printers-tests = $(link-libc-rpath) \
>  rpath-dirs = math elf dlfcn nss nis rt resolv mathvec support
>  rpath-link = \
>  $(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%)))
> +
> +# See $(elf-stub-dso-files) in elf/Makefile.
> +rpath-link-stubs=:$(common-objdir)/elf/stub-dsos
> +
>  else  # build-static
>  link-libc = $(common-objpfx)libc.a $(otherlibs) $(gnulib) $(common-objpfx)libc.a $(gnulib)
>  link-libc-tests = $(common-objpfx)libc.a $(otherlibs) $(gnulib-tests) $(common-objpfx)libc.a $(gnulib-tests)

Ok.

> diff --git a/elf/Makefile b/elf/Makefile
> index 834ec858a8..5f179bae19 100644
> --- a/elf/Makefile
> +++ b/elf/Makefile
> @@ -505,7 +505,23 @@ ifeq (yes,$(build-shared))
>  # to run programs during the `make others' pass.
>  lib-noranlib: $(objpfx)$(rtld-installed-name) \
>  	      $(addprefix $(objpfx),$(extra-objs))
> -endif
> +
> +# The system may have installed DSO that no longer exist as separate
> +# DSOs in the current glibc version.  The link editor will try to
> +# resolve versioned GLIBC_PRIVATE symbol references in them against
> +# libc.so, but these exports do not exist anymore.  Supplying these
> +# stub DSOs in a directory searched by -rpath-link prevents the link
> +# editor from picking up the installed system files.
> +ifneq ($(strip $(elf-stub-dsos)),)
> +elf-stub-dso-files :=\
> +$(foreach L,$(elf-stub-dsos),$(objpfx)/stub-dsos/lib$L.so$(lib$L.so-version))
> +$(elf-stub-dso-files): lib-stub.S
> +	$(make-target-directory)
> +	$(LINK.o) -shared -o $@ -B$(csu-objpfx) $(LDFLAGS.so) \
> +	  -Wl,-soname=$(@F) -nostdlib $<
> +subdir_lib: $(elf-stub-dso-files)
> +endif # $(elf-stub-dsos)
> +endif # $(build-shared)
>  
>  # Command to link into a larger single relocatable object.
>  reloc-link = $(LINK.o) -nostdlib -nostartfiles -r
> diff --git a/elf/lib-stub.S b/elf/lib-stub.S
> new file mode 100644
> index 0000000000..2b5ae2010e
> --- /dev/null
> +++ b/elf/lib-stub.S
> @@ -0,0 +1,22 @@
> +/* Assembler source file for creating stub libraries.
> +   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/>.  */
> +
> +	/* Produce an invalid init function, so that loading the stub
> +	   crashes.  */
> +	.section .init_array,"a",%init_array
> +	.dc.a 4096
>
  
Adhemerval Zanella May 24, 2021, 6:25 p.m. UTC | #2
On 24/05/2021 15:24, Adhemerval Zanella wrote:
> 
> 
> On 18/05/2021 11:25, Florian Weimer via Libc-alpha wrote:
>> And reference the elf/stub-dsos directory when linking installed
>> programs.
> 
> So if I understood correctly, this is to trigger an invalid runtime
> to avoid linking against system GLIBC_PRIVATE symbols, right?
> 
> I am not sure I fully understand the lib-stub trick here, how
> exactly the lib-stub is preventing the wrong linkage here? And why
> is this required for the libpthread move (my feeling this is orthogonal
> to the project).

Nevermind, I am not sure why I replied to the older version of the
patchset.
  

Patch

diff --git a/Makeconfig b/Makeconfig
index 1d5e45926c..3ef71cc02b 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -425,7 +425,8 @@  ifndef +link-pie
 	     $(link-extra-libs)
 +link-pie-after-libc = $(+postctorS) $(+postinit)
 define +link-pie
-$(CC) $(link-libc-rpath-link) $(+link-pie-before-libc) $(rtld-LDFLAGS) \
+$(CC) $(link-libc-rpath-link)$(rpath-link-stubs) \
+  $(+link-pie-before-libc) $(rtld-LDFLAGS) \
   $(link-extra-flags) $(link-libc) $(+link-pie-after-libc)
 $(call after-link,$@)
 endef
@@ -487,7 +488,8 @@  else  # not build-pie-default
 	      $(link-extra-libs)
 +link-after-libc = $(+postctor) $(+postinit)
 define +link
-$(CC) $(link-libc-rpath-link) $(+link-before-libc) $(rtld-LDFLAGS) \
+$(CC) $(link-libc-rpath-link)$(rpath-link-stubs) \
+  $(+link-before-libc) $(rtld-LDFLAGS) \
   $(link-extra-flags) $(link-libc) $(+link-after-libc)
 $(call after-link,$@)
 endef
@@ -581,6 +583,10 @@  link-libc-printers-tests = $(link-libc-rpath) \
 rpath-dirs = math elf dlfcn nss nis rt resolv mathvec support
 rpath-link = \
 $(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%)))
+
+# See $(elf-stub-dso-files) in elf/Makefile.
+rpath-link-stubs=:$(common-objdir)/elf/stub-dsos
+
 else  # build-static
 link-libc = $(common-objpfx)libc.a $(otherlibs) $(gnulib) $(common-objpfx)libc.a $(gnulib)
 link-libc-tests = $(common-objpfx)libc.a $(otherlibs) $(gnulib-tests) $(common-objpfx)libc.a $(gnulib-tests)
diff --git a/elf/Makefile b/elf/Makefile
index 834ec858a8..5f179bae19 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -505,7 +505,23 @@  ifeq (yes,$(build-shared))
 # to run programs during the `make others' pass.
 lib-noranlib: $(objpfx)$(rtld-installed-name) \
 	      $(addprefix $(objpfx),$(extra-objs))
-endif
+
+# The system may have installed DSO that no longer exist as separate
+# DSOs in the current glibc version.  The link editor will try to
+# resolve versioned GLIBC_PRIVATE symbol references in them against
+# libc.so, but these exports do not exist anymore.  Supplying these
+# stub DSOs in a directory searched by -rpath-link prevents the link
+# editor from picking up the installed system files.
+ifneq ($(strip $(elf-stub-dsos)),)
+elf-stub-dso-files :=\
+$(foreach L,$(elf-stub-dsos),$(objpfx)/stub-dsos/lib$L.so$(lib$L.so-version))
+$(elf-stub-dso-files): lib-stub.S
+	$(make-target-directory)
+	$(LINK.o) -shared -o $@ -B$(csu-objpfx) $(LDFLAGS.so) \
+	  -Wl,-soname=$(@F) -nostdlib $<
+subdir_lib: $(elf-stub-dso-files)
+endif # $(elf-stub-dsos)
+endif # $(build-shared)
 
 # Command to link into a larger single relocatable object.
 reloc-link = $(LINK.o) -nostdlib -nostartfiles -r
diff --git a/elf/lib-stub.S b/elf/lib-stub.S
new file mode 100644
index 0000000000..2b5ae2010e
--- /dev/null
+++ b/elf/lib-stub.S
@@ -0,0 +1,22 @@ 
+/* Assembler source file for creating stub libraries.
+   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/>.  */
+
+	/* Produce an invalid init function, so that loading the stub
+	   crashes.  */
+	.section .init_array,"a",%init_array
+	.dc.a 4096