This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] ld.so: Support moving versioned symbols between sonames [BZ #24741]


Hi,

Le jeudi 27 juin 2019 à 16:43 +0200, Florian Weimer a écrit :
> This change should be fully backwards-compatible because the old
> code aborted the load if a soname mismatch was encountered
> (instead of searching further for a matching symbol).  This means
> that no different symbols are found.
> 
> The soname check was explicitly disabled for the skip_map != NULL
> case.  However, this only happens with dl(v)sym and RTLD_NEXT,
> and those lookups do not come with a verneed entry that could be used
> for the check.
> 
> The error check was already explicitly disabled for the skip_map !=
> NULL case, that is, when dl(v)sym was called with RTLD_NEXT.  But
> _dl_vsym always sets filename in the struct r_found_version argument
> to NULL, so the check was not active anyway.  This means that
> symbol lookup results for the skip_map != NULL case do not change,
> either.
> 
> 2019-06-27  Florian Weimer  <fweimer@redhat.com>
> 
> 	[BZ #24741]
> 	* elf/dl-lookup.c (do_lookup_x): Do not fail if there is a soname
> 	mismatch in a versioned symbol reference.
> 	(_dl_lookup_symbol_x): Do not report soname mismatch failures.
> 	* elf/Makefile [$(build-shared)] (tests): Add tst-sonamemove,
> 	tst-sonamemove-dlopen.
> 	(module-names): Add tst-sonamemove-linkmod1,
> 	tst-sonamemove-runmod1, tst-sonamemove-runmod2.
> 	(LDFLAGS-tst-sonamemove-linkmod1.so): Set.
> 	(LDFLAGS-tst-sonamemove-runmod1.so): Likewise.
> 	(LDFLAGS-tst-sonamemove-runmod2.so): Likewise.
> 	(tst-sonamemove-runmod1.so): Link against
> 	tst-sonamemove-runmod2.so.
> 	(tst-sonamemove): Link against tst-sonamemove-linkmod1.so.
> 	(tst-sonamemove.out): Depend on tst-sonamemove-runmod1.so,
> 	tst-sonamemove-runmod2.so.
> 	(tst-sonamemove-dlopen.out): Likewise.
> 	* elf/tst-sonamemove.c: New file.
> 	* elf/tst-sonamemove-dlopen.c: Likewise.
> 	* elf/tst-sonamemove-linkmod1.c: Likewise.
> 	* elf/tst-sonamemove-linkmod1.map: Likewise.
> 	* elf/tst-sonamemove-runmod1.c: Likewise.
> 	* elf/tst-sonamemove-runmod1.map: Likewise.
> 	* elf/tst-sonamemove-runmod2.c: Likewise.
> 	* elf/tst-sonamemove-runmod2.map: Likewise.
> 	* support/xdlfcn.h (xdlvsym): Declare function.
> 	* support/xdlfcn.c (xdlvsym): Define funciton.
> 
> diff --git a/NEWS b/NEWS
> index 8a2fecef47..8cea9f5825 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -34,6 +34,12 @@ Major new features:
>    pointer subtraction within the allocated object, where results might
>    overflow the ptrdiff_t type.
>  
> +* The dynamic linker no longer refuses to load objects which reference
> +  versioned symbols whose implementation has moved to a different soname
> +  since the object has been linked.  The old error message, symbol
> +  FUNCTION-NAME, version SYMBOL-VERSION not defined in file DSO-NAME with
> +  link time reference, is gone.
> +
>  Deprecated and removed features, and other changes affecting compatibility:
>  
>  * The functions clock_gettime, clock_getres, clock_settime,
> diff --git a/elf/Makefile b/elf/Makefile
> index 27a2fa8c14..76b0565054 100644
> --- a/elf/Makefile
> +++ b/elf/Makefile
> @@ -191,7 +191,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
>  	 tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \
>  	 tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \
>  	 tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \
> -	 tst-unwind-ctor tst-unwind-main tst-audit13
> +	 tst-unwind-ctor tst-unwind-main tst-audit13 \
> +	 tst-sonamemove tst-sonamemove-dlopen

tst-sonamemove could be name tst-sonamemove-link to make obvious the
difference with -dlopen.

>  #	 reldep9
>  tests-internal += loadtest unload unload2 circleload1 \
>  	 neededtest neededtest2 neededtest3 neededtest4 \
> @@ -281,7 +282,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
>  		tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \
>  		tst-main1mod tst-libc_dlvsym-dso tst-absolute-sym-lib \
>  		tst-absolute-zero-lib tst-big-note-lib tst-unwind-ctor-lib \
> -		tst-audit13mod1
> +		tst-audit13mod1 tst-sonamemove-linkmod1 \
> +		tst-sonamemove-runmod1 tst-sonamemove-runmod2
>  # Most modules build with _ISOMAC defined, but those filtered out
>  # depend on internal headers.
>  modules-names-tests = $(filter-out ifuncmod% tst-libc_dlvsym-dso tst-tlsmod%,\
> @@ -1410,6 +1412,28 @@ $(objpfx)tst-audit13.out: $(objpfx)tst-audit13mod1.so
>  LDFLAGS-tst-audit13mod1.so = -Wl,-z,lazy
>  tst-audit13-ENV = LD_AUDIT=$(objpfx)tst-audit13mod1.so
>  
> +# tst-sonamemove links against an older implementation of the library.
> +LDFLAGS-tst-sonamemove-linkmod1.so = \
> +  -Wl,--version-script=tst-sonamemove-linkmod1.map \
> +  -Wl,-soname,tst-sonamemove-runmod1.so
> +LDFLAGS-tst-sonamemove-runmod1.so = -Wl,--no-as-needed \
> +  -Wl,--version-script=tst-sonamemove-runmod1.map \
> +  -Wl,-soname,tst-sonamemove-runmod1.so
> +LDFLAGS-tst-sonamemove-runmod2.so = \
> +  -Wl,--version-script=tst-sonamemove-runmod2.map \
> +  -Wl,-soname,tst-sonamemove-runmod2.so
> +$(objpfx)tst-sonamemove-runmod1.so: $(objpfx)tst-sonamemove-runmod2.so
> +# Link against the link module, but depend on the run-time modules
> +# for execution.
> +$(objpfx)tst-sonamemove: $(objpfx)tst-sonamemove-linkmod1.so
> +$(objpfx)tst-sonamemove.out: \
> +  $(objpfx)tst-sonamemove-runmod1.so \
> +  $(objpfx)tst-sonamemove-runmod2.so
> +$(objpfx)tst-sonamemove-dlopen: $(libdl)
> +$(objpfx)tst-sonamemove.out: \
> +  $(objpfx)tst-sonamemove-runmod1.so \
> +  $(objpfx)tst-sonamemove-runmod2.so
> +

The last three lines duplicate those above.


>  # Override -z defs, so that we can reference an undefined symbol.
>  # Force lazy binding for the same reason.
>  LDFLAGS-tst-latepthreadmod.so = \

[...]

> diff --git a/elf/tst-sonamemove-dlopen.c b/elf/tst-sonamemove-dlopen.c
> new file mode 100644
> index 0000000000..c496705044
> --- /dev/null
> +++ b/elf/tst-sonamemove-dlopen.c
> @@ -0,0 +1,35 @@
> +/* Check that a moved versioned symbol can be found using dlsym, dlvsym.
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>;.  */
> +
> +#include <stddef.h>
> +#include <support/check.h>
> +#include <support/xdlfcn.h>
> +
> +static int
> +do_test (void)
> +{
> +  /* tst-sonamemove-runmod1.so does not define moved_function, but it
> +     depends on tst-sonamemove-runmod2.so, which does.  */
> +  void *handle = xdlopen ("tst-sonamemove-runmod1.so", RTLD_NOW);
> +  TEST_VERIFY (xdlsym (handle, "moved_function") != NULL);
> +  TEST_VERIFY (xdlvsym (handle, "moved_function", "SONAME_MOVE") != NULL);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/elf/tst-sonamemove-linkmod1.c b/elf/tst-sonamemove-linkmod1.c
> new file mode 100644
> index 0000000000..b8a354e5e3
> --- /dev/null
> +++ b/elf/tst-sonamemove-linkmod1.c
> @@ -0,0 +1,25 @@
> +/* Link interface for (lack of) soname matching in versioned symbol refs.
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>;.  */
> +
> +/* This function moved from tst-sonamemove-runmod1.so.  This module is
> +   intended for linking only, to simulate an old application which was
> +   linked against an older version of the library.  */
> +void
> +moved_function (void)
> +{
> +}
> diff --git a/elf/tst-sonamemove-linkmod1.map b/elf/tst-sonamemove-linkmod1.map
> new file mode 100644
> index 0000000000..8fe5904018
> --- /dev/null
> +++ b/elf/tst-sonamemove-linkmod1.map
> @@ -0,0 +1,3 @@
> +SONAME_MOVE {
> +  global: moved_function;
> +};
> diff --git a/elf/tst-sonamemove-runmod1.c b/elf/tst-sonamemove-runmod1.c
> new file mode 100644
> index 0000000000..5c409e2289
> --- /dev/null
> +++ b/elf/tst-sonamemove-runmod1.c
> @@ -0,0 +1,23 @@
> +/* Run-time module whose moved_function moved to a library dependency.
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>;.  */
> +
> +/* Dummy function to add the required symbol version.  */
> +void
> +other_function (void)
> +{
> +}
> diff --git a/elf/tst-sonamemove-runmod1.map b/elf/tst-sonamemove-runmod1.map
> new file mode 100644
> index 0000000000..2ea81c6e6f
> --- /dev/null
> +++ b/elf/tst-sonamemove-runmod1.map
> @@ -0,0 +1,3 @@
> +SONAME_MOVE {
> +  global: other_function;
> +};
> diff --git a/elf/tst-sonamemove-runmod2.c b/elf/tst-sonamemove-runmod2.c
> new file mode 100644
> index 0000000000..b5e482eff5
> --- /dev/null
> +++ b/elf/tst-sonamemove-runmod2.c
> @@ -0,0 +1,24 @@
> +/* Run-time module with the actual implementation of moved_function.
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>;.  */
> +
> +/* In the test scenario, this function was originally in
> +   tst-sonamemove-runmod1.so.  */
> +void
> +moved_function (void)
> +{
> +}
> diff --git a/elf/tst-sonamemove-runmod2.map b/elf/tst-sonamemove-runmod2.map
> new file mode 100644
> index 0000000000..8fe5904018
> --- /dev/null
> +++ b/elf/tst-sonamemove-runmod2.map
> @@ -0,0 +1,3 @@
> +SONAME_MOVE {
> +  global: moved_function;
> +};
> diff --git a/elf/tst-sonamemove.c b/elf/tst-sonamemove.c
> new file mode 100644
> index 0000000000..a80ebcb36f
> --- /dev/null
> +++ b/elf/tst-sonamemove.c
> @@ -0,0 +1,30 @@
> +/* Check that a versioned symbol can move from one library to another.
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>;.  */
> +
> +/* moved_function is linked against tst-sonamemove-runmod1.so, but the
> +   actual implementation is in tst-sonamemove-runmod1.so. */

I found this comment unclear. tst-sonamemove is linked against tst-
sonamemove-linkmod1.so, which has tst-sonamemove-runmod1.so soname.
When tst-sonamemove is run, tst-sonamemove-runmod1.so is loaded, which
imply loading tst-sonamemove-runmod2.so as a dependency. tst-
sonamemove-runmod2.so is where move_function's implementation is.

> +void moved_function (void);
> +
> +static int
> +do_test (void)
> +{
> +  moved_function ();
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>

Regards.

-- 
Yann Droneaud
OPTEYA




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]