From nobody Fri May 13 11:16:39 2022 X-Original-To: freebsd-current@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 8A96D1ACE50E for ; Fri, 13 May 2022 11:17:41 +0000 (UTC) (envelope-from obiwac@gmail.com) Received: from mail-pj1-x1036.google.com (mail-pj1-x1036.google.com [IPv6:2607:f8b0:4864:20::1036]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1D4" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4L05j05n61z3kxg for ; Fri, 13 May 2022 11:17:40 +0000 (UTC) (envelope-from obiwac@gmail.com) Received: by mail-pj1-x1036.google.com with SMTP id j10-20020a17090a94ca00b001dd2131159aso10564318pjw.0 for ; Fri, 13 May 2022 04:17:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:from:date:message-id:subject:to; bh=C2/CJeJEvzqmZ8OtlURgWVAglodL1sS3ZseuGxwSiQc=; b=C9QIGiQFqz4z4UnVMIzdKqgvfCZyTk87YMXAHVtwF4SiA2Wpc+ILGcelqPbtjGYZUz 8IrQZVf5fqPKS9gQQ2+PNGe4pNV6SNbgV7LzpmCMH6CL/7xPGlcPiVrGv/3wbAQfvnao gl/hDVRq0ovmavGLRCxjnle5EPzUdHZi+VaHEp4N0GEM/nN5w+ywFiUnpdc0WINAyvE3 opCSQyWRVBKOzhk9jXlSlGU8kaHf3a0GDo6eyNu5pEdX2OYZkku00EkXCh3RQa5RgJ9v 7wFrrGiEq5pumwwg88HsZGD5sJdmGmOycL3FNyjHbzyhoaidxaSxET1x60Xl6lxRADle NCFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=C2/CJeJEvzqmZ8OtlURgWVAglodL1sS3ZseuGxwSiQc=; b=pbVACtUV4Io+EDZdFJWUWg1EnOqgz+yHZPfhg8KgbQY7bW/dIKVZKLgKTev6xhx1b7 ObSwvvmo8eJ8+RzQ/ZWb909kDdhQbnixzjowMq+Yz6XKUZR49LzbBpcQoPkYq42Z7lXD c5Fnt/4GYpOKvvQOznI63Ch1+lfmWNzPm56wHVyUU4aaW6fnkzJvM5nS7pKsYGCsVqH5 ibje0SBZ0oNYJPRkSsH9djlU3jb4AEB3wTNHpIyxgH6INx1DwGynw5G3TPvw2HAz83y6 Vmh2sFmFHXpChKj2L33RRRwJg1kam6O+h3Jn2D90KrIlhkzrO9PSYZaXLjKyCUV3zsFQ YgCA== X-Gm-Message-State: AOAM530h2iOdHR6I749d0Tn2/D1G1FtOf3vxdRsrJWum04UyH7kL4Ke9 9U16JObpkbxUfaulmUAw5wFAjPnoclT+t92gj0K7oTWzwlw= X-Google-Smtp-Source: ABdhPJw1LTdiNDJsh9psqom860ujgvk6zxERwezV4K67Ox3GTELPIS1fYhbUw39OYv333sPwWc/zyxHE8N4YH7AyOKU= X-Received: by 2002:a17:902:bf06:b0:156:af5b:e6c with SMTP id bi6-20020a170902bf0600b00156af5b0e6cmr4083944plb.147.1652440653511; Fri, 13 May 2022 04:17:33 -0700 (PDT) List-Id: Discussions about the use of FreeBSD-current List-Archive: https://lists.freebsd.org/archives/freebsd-current List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-current@freebsd.org MIME-Version: 1.0 From: obiwac Date: Fri, 13 May 2022 13:16:39 +0200 Message-ID: Subject: rtld: Relocation from unversioned binary matches oldest version instead of "default" To: freebsd-current@freebsd.org Content-Type: text/plain; charset="UTF-8" X-Rspamd-Queue-Id: 4L05j05n61z3kxg X-Spamd-Bar: --- Authentication-Results: mx1.freebsd.org; dkim=pass header.d=gmail.com header.s=20210112 header.b=C9QIGiQF; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (mx1.freebsd.org: domain of obiwac@gmail.com designates 2607:f8b0:4864:20::1036 as permitted sender) smtp.mailfrom=obiwac@gmail.com X-Spamd-Result: default: False [-3.90 / 15.00]; ARC_NA(0.00)[]; NEURAL_HAM_MEDIUM(-1.00)[-1.000]; R_DKIM_ALLOW(-0.20)[gmail.com:s=20210112]; FROM_HAS_DN(0.00)[]; R_SPF_ALLOW(-0.20)[+ip6:2607:f8b0:4000::/36:c]; FREEMAIL_FROM(0.00)[gmail.com]; MIME_GOOD(-0.10)[text/plain]; PREVIOUSLY_DELIVERED(0.00)[freebsd-current@freebsd.org]; TO_DN_NONE(0.00)[]; RCPT_COUNT_ONE(0.00)[1]; NEURAL_HAM_LONG(-1.00)[-1.000]; MID_RHS_MATCH_FROMTLD(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; DKIM_TRACE(0.00)[gmail.com:+]; DMARC_POLICY_ALLOW(-0.50)[gmail.com,none]; RCVD_IN_DNSWL_NONE(0.00)[2607:f8b0:4864:20::1036:from]; NEURAL_HAM_SHORT(-0.90)[-0.904]; MLMMJ_DEST(0.00)[freebsd-current]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+]; FREEMAIL_ENVFROM(0.00)[gmail.com]; ASN(0.00)[asn:15169, ipnet:2607:f8b0::/32, country:US]; RCVD_COUNT_TWO(0.00)[2]; RCVD_TLS_ALL(0.00)[]; DWL_DNSWL_NONE(0.00)[gmail.com:dkim] X-ThisMailContainsUnwantedMimeParts: N Wassup, This may not be strictly speaking a bug with rtld, but it sure is weird/awkward behaviour considering the existing information I could gather. In an unversioned shared object which references a symbol which has multiple versions (e.g. readdir@@FBSD_1.5 & readdir@FBSD_1.0, found with 'readelf -s /lib/libc.so.7 | grep readdir@'), the dynamic linker always selects the oldest version (so readdir@FBSD_1.0 in this case). But as I understand it from documents such as [1], shouldn't the default symbol (readdir@@FBSD_1.5) be used instead? ("Default" means "unhidden" in the context of rtld afaiu, i.e. a symbol where '!(versym & VER_NDX_HIDDEN)'.) The code in question in rtld which exhibits this behaviour is in 'libexec/rtld-elf/rtld.c:matched_symbol': /* * If we are not called from dlsym (i.e. this is a normal * relocation from unversioned binary, accept the symbol * immediately if it happens to have first version after * this shared object became versioned. Otherwise, if * symbol is versioned and not hidden, remember it. If it * is the only symbol with this name exported by the * shared object, it will be returned as a match at the * end of the function. If symbol is global (verndx < 2) * accept it unconditionally. */ if ((req->flags & SYMLOOK_DLSYM) == 0 && verndx == VER_NDX_GIVEN) { result->sym_out = symp; return (true); } else if (verndx >= VER_NDX_GIVEN) { if ((versym & VER_NDX_HIDDEN) == 0) { if (result->vsymp == NULL) result->vsymp = symp; result->vcount++; } return (false); } I imagine the intention behind this is to not break older unversioned shared objects if the default symbol for a certain function it uses is updated while the older version is still provided, but it makes it such that you're forced to provide a version for your symbols in newer programs. This means the common method for creating shared objects for instance is incorrect and yields difficult to debug errors, e.g. in the case of readdir, where a new program will use the new 'dirent' structure, but 'readdir' will be in reality relocated to 'freebsd11_readdir', which assumes the use of 'freebsd11_dirent': % cc -g -fPIC -c lib.c -o lib.o % ld -shared lib.o -o liblib.so % readelf -sD liblib.so | grep readdir # shows readdir unversioned 4: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND readdir Simple fix on the user's end would be to force 'liblib.so' to use versioned symbols: % ld -shared lib.o -o liblib.so /lib/libc.so.7 % readelf -sD liblib.so | grep readdir # shows readdir versioned 4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND readdir@FBSD_1.5 (3) But that's a bit awkward I feel, and I don't see anyone suggesting to do such a thing. One other bit of weirdness is that LLVM equivalents to GNU tools (e.g. 'llvm-objdump') don't seem to have/care about the notion of a "default" version: % objdump -T /lib/libc.so.7 | grep readdir 00000000000af200 g DF .text 00000000000000be FBSD_1.5 readdir_r 00000000000af3b0 g DF .text 00000000000000ed (FBSD_1.0) readdir_r 00000000000af1a0 g DF .text 0000000000000053 FBSD_1.5 readdir 00000000000af2c0 g DF .text 00000000000000ed (FBSD_1.0) readdir % llvm-objdump -T /lib/libc.so.7 | grep readdir 00000000000af200 g DF .text 00000000000000be readdir_r 00000000000af3b0 g DF .text 00000000000000ed readdir_r 00000000000af1a0 g DF .text 0000000000000053 readdir 00000000000af2c0 g DF .text 00000000000000ed readdir This difference in functionality is very frustratingly not mentioned anywhere that I can find in llvm-objdump's documentation, but perhaps this is an indication that unversioned binaries are deprecated and should not be used at all going forward? I don't know, and it irks me quite a bit I can't find any information about this. Currently I'm using a patched version of rtld which behaves the way I understood it should, but I'm still asking here to clarify things, because this stuff has given me quite a few questions and I can't seem to find very many answers. Perhaps kib@ could help with this? [1]: https://people.freebsd.org/~deischen/symver/library_versioning.txt