[09/10] elf: Add facility to create stub DSOs in elf/stub-dsos
Checks
Commit Message
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
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
>
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.
@@ -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)
@@ -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
new file mode 100644
@@ -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