From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 72410 invoked by alias); 16 Mar 2018 15:35:19 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Received: (qmail 72398 invoked by uid 89); 16 Mar 2018 15:35:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_NONE autolearn=no version=3.3.2 spammy= X-HELO: mail-qt0-f171.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=UW0/RdqAu73zTTNCjoVwUeJXPlSWq8Hht921xMVi8fU=; b=c9+iIjo3CK+45cB9gk7grN5xOcxq7HAeBA/0+1rFXi2LMgcFDN2vSYYfVb5lRw/pkE jKG4EnwpoeghZedHDVAO2gpD20skIpB0xORw414B965K06BSDO9adfnb62VhHEXQgqn8 2nECmuus4qy/3m4FMALDjth1JA/f7oMOfLVDB3+nHZOU/s6KndAQaYl9ENP9ghC1line rjgr5YOKbctWpSQ8CW2y/2W6yt2F3IVRKMvg2FqXEnx8GRPcJ+CfLB3/mo0rW3PG5ozu An700DXNQQ0LDuLj/IjR7q9uoXCS6V/tL8cetjAOVzTc9E2udYi/D7Qrr6xMN0rNUTh2 TQIQ== X-Gm-Message-State: AElRT7GmOAXhofZh2z+rzU0zieDU7x/BHlex4zfv6jw3Mtx7niBoBVOx QKwyDeohpxW9ev02YZhUE3EOLHUDB14= X-Google-Smtp-Source: AG47ELv5Z2Uh5sW0esvyjX753uXyNyPqrDStWUdRId/Qyw/yFr0+RAtU4quLNjLKRXJsS9w5HUQmEQ== X-Received: by 10.237.58.168 with SMTP id o37mr3519377qte.334.1521214514999; Fri, 16 Mar 2018 08:35:14 -0700 (PDT) Subject: Re: Are the pthread "compatibility" copies of symbols in libc still necessary? To: Florian Weimer , Zack Weinberg , GNU C Library References: <2b40c294-fd0a-048d-06d5-c872f381729d@redhat.com> From: Carlos O'Donell Message-ID: Date: Fri, 16 Mar 2018 15:35:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: <2b40c294-fd0a-048d-06d5-c872f381729d@redhat.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-SW-Source: 2018-03/txt/msg00403.txt.bz2 On 03/16/2018 08:41 AM, Florian Weimer wrote: > On 03/16/2018 03:30 PM, Zack Weinberg wrote: >> A number of source files that properly belong to libc.so are also >> compiled as part of libpthread, with a note that this is for >> "compatibility for old binaries".  The exact set varies based on >> architecture, but includes basic things like read, write, and fork - I >> _think_ there was a difference in semantics in the distant past, >> having something to do with thread cancellation. > > They are still needed because versioned symbols also embed a DSO name, and the dynamic linker checks that if it has not been interposed. > > I think it's this code in elf/dl-lookup.c: > >       if (__glibc_unlikely (res < 0) && skip_map == NULL) >     { >       /* Oh, oh.  The file named in the relocation entry does not >          contain the needed symbol.  This code is never reached >          for unversioned lookups.  */ >       assert (version != NULL); >       const char *reference_name = undef_map ? undef_map->l_name : ""; >       struct dl_exception exception; >       /* XXX We cannot translate the message.  */ >       _dl_exception_create_format >         (&exception, DSO_FILENAME (reference_name), >          "symbol %s version %s not defined in file %s" >          " with link time reference%s", >          undef_name, version->name, version->filename, >          res == -2 ? " (no version symbols)" : ""); >       _dl_signal_cexception (0, &exception, N_("relocation error")); >       _dl_exception_free (&exception); >       *ref = NULL; >       return 0; >     } > > This is required by the GNU symbol versioning spec, but I don't know why. The specification says the data must be recorded, but it doesn't say what you have to *do* with the data? I am of the opinion that this is simply to produce a reasonable error message if the versioned symbol is missing completely. We should probably reach out to Ulrich to see if has any opinion on this, as the primary author of the specification he might have an input here. My own opinion is that the check is overly restrictive, and that we could relax it to allow versioned symbols to move to other shared objects. > Even new binaries use these symbols: > > $ LD_DEBUG=bindings systemctl |& grep binding.*system.*libpthread.*[^_]fork >      11905:    binding file /usr/lib/systemd/libsystemd-shared-234.so [0] to /lib64/libpthread.so.0 [0]: normal symbol `fork' [GLIBC_2.2.5] >      11905:    binding file systemctl [0] to /lib64/libpthread.so.0 [0]: normal symbol `fork' [GLIBC_2.2.5] > > This may be a linker bug because at least fork is a compat symbol. Is it though? libc.so.6 has fork@@GLIBC_2.2.5, which causes the binary to have a reference to fork@GLIBC_2.2.5, and that's correct. However, now we have both libc.so.6 and libpthread.so.0 with definitions of fork at GLIBC_2.2.5. Also libsystemd-shared-234.so has: 000000000043f580 0000019a00000007 R_X86_64_JUMP_SLOT 0000000000000000 fork@GLIBC_2.2.5 + 0 410: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fork@GLIBC_2.2.5 (2) 0x0170: Version: 1 File: libc.so.6 Cnt: 16 ... 0x0270: Name: GLIBC_2.2.5 Flags: none Version: 2 Is it a dynamic loader bug that the compat symbol was selected? systemctl has libpthread.so.0 as the *first* DT_NEEDED entry, and we process them in order. 0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x0000000000000001 (NEEDED) Shared library: [libsystemd-shared-234.so] 0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1] So libpthread.so.0 interposes the versioned symbol from libc.so.6. 26067: Initial object scopes 26067: object=systemctl [0] 26067: scope 0: systemctl /lib64/libpthread.so.0 /lib64/libc.so.6 /usr/lib/systemd/libsystemd-shared-234.so /lib64/libgcc_s.so.1 /lib64/ld-linux-x86-64.so.2 /lib64/librt.so.1 /lib64/libcap.so.2 /lib64/libacl.so.1 /lib64/libcryptsetup.so.4 /lib64/libgcrypt.so.20 /lib64/libip4tc.so.0 /lib64/libseccomp.so.2 /lib64/libselinux.so.1 /lib64/libidn.so.11 /lib64/liblzma.so.5 /lib64/liblz4.so.1 /lib64/libblkid.so.1 /lib64/libattr.so.1 /lib64/libuuid.so.1 /lib64/libdevmapper.so.1.02 /lib64/libdl.so.2 /lib64/libgpg-error.so.0 /lib64/libpcap.so.1 /lib64/libpcre2-8.so.0 /lib64/libsepol.so.1 /lib64/libudev.so.1 /lib64/libm.so.6 26067: So the search scope is libpthread *first*. The above error never triggers because libc.so.6 *does* have the named versioned symbol, but libpthread.so.0 also has it too. My conclusion is this: * We can remove fork@GLIBC_2.2.5 from libpthread.so, the shared object doesn't encode it as being needed and won't cause a failure per the rules that require the referenced shared object to have the versioned symbol that was bound at static link time. Cheers, Carlos.