Bug 24741 - ld.so should not require that a versioned symbol is always implemented in the same library
Summary: ld.so should not require that a versioned symbol is always implemented in the...
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: dynamic-link (show other bugs)
Version: 2.30
: P2 enhancement
Target Milestone: 2.30
Assignee: Florian Weimer
URL:
Keywords:
Depends on:
Blocks: 20188 20220 24959
  Show dependency treegraph
 
Reported: 2019-06-27 12:05 UTC by Florian Weimer
Modified: 2020-02-15 10:05 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Florian Weimer 2019-06-27 12:05:10 UTC
ld.so currently performs a check which requires that a versioned symbol is implemented in the same shared object in which it was found at link time.

The error message looks like this:

symbol FUNCTION-NAME, version SYMBOL-VERSION not defined in file DSO-NAME with link time reference

This check constrains the evolution of shared objects because implementations cannot be moved to dependent objects.  This check is only applied to versioned symbols, and therefore versioned symbols are less powerful than unversioned symbols in this context.

The presence of this check requires that we add wrapper functions each time we move a function from a secondary library into libc.so.
Comment 1 Sourceware Commits 2019-06-28 08:36:35 UTC
The master branch has been updated by Florian Weimer <fw@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=f0b2132b35248c1f4a80f62a2c38cddcc802aa8c

commit f0b2132b35248c1f4a80f62a2c38cddcc802aa8c
Author: Florian Weimer <fweimer@redhat.com>
Date:   Fri Jun 28 10:12:50 2019 +0200

    ld.so: Support moving versioned symbols between sonames [BZ #24741]
    
    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.
Comment 2 Florian Weimer 2019-06-28 08:38:36 UTC
Fixed in glibc 2.30.
Comment 3 Sourceware Commits 2019-07-02 15:06:33 UTC
The master branch has been updated by Florian Weimer <fw@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=41d6f74e6cb6a92ab428c11ee1e408b2a16aa1b0

commit 41d6f74e6cb6a92ab428c11ee1e408b2a16aa1b0
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Jul 2 15:12:20 2019 +0200

    nptl: Remove vfork IFUNC-based forwarder from libpthread [BZ #20188]
    
    With commit f0b2132b35248c1f4a80f62a2c38cddcc802aa8c ("ld.so:
    Support moving versioned symbols between sonames [BZ #24741]"), the
    dynamic linker will find the definition of vfork in libc and binds
    a vfork reference to that symbol, even if the soname in the version
    reference says that the symbol should be located in libpthread.
    
    As a result, the forwarder (whether it's IFUNC-based or a duplicate
    of the libc implementation) is no longer necessary.
    
    On older architectures, a placeholder symbol is required, to make sure
    that the GLIBC_2.1.2 symbol version does not go away, or is turned in
    to a weak symbol definition by the link editor.  (The symbol version
    needs to preserved so that the symbol coverage check in
    elf/dl-version.c does not fail for old binaries.)
    
    mips32 is an outlier: It defined __vfork@@GLIBC_2.2, but the
    baseline is GLIBC_2.0.  Since there are other @@GLIBC_2.2 symbols,
    the placeholder symbol is not needed there.
Comment 4 Sourceware Commits 2020-02-15 10:05:08 UTC
The master branch has been updated by Florian Weimer <fw@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=3a0ecccb599a6b1ad4b149dc569c0080e92d057b

commit 3a0ecccb599a6b1ad4b149dc569c0080e92d057b
Author: Florian Weimer <fweimer@redhat.com>
Date:   Sat Feb 8 19:58:43 2020 +0100

    ld.so: Do not export free/calloc/malloc/realloc functions [BZ #25486]
    
    Exporting functions and relying on symbol interposition from libc.so
    makes the choice of implementation dependent on DT_NEEDED order, which
    is not what some compiler drivers expect.
    
    This commit replaces one magic mechanism (symbol interposition) with
    another one (preprocessor-/compiler-based redirection).  This makes
    the hand-over from the minimal malloc to the full malloc more
    explicit.
    
    Removing the ABI symbols is backwards-compatible because libc.so is
    always in scope, and the dynamic loader will find the malloc-related
    symbols there since commit f0b2132b35248c1f4a80f62a2c38cddcc802aa8c
    ("ld.so: Support moving versioned symbols between sonames
    [BZ #24741]").
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>